Minor fixes to comments.
[AROS.git] / rom / intuition / windecorclass.c
blob41622a778fe737ffcf6ab39594fa738e6152565b
1 /*
2 Copyright 1995-2012, The AROS Development Team. All rights reserved.
3 Copyright 2001-2003, The MorphOS Development Team. All Rights Reserved.
4 $Id$
5 */
8 #include <dos/dos.h>
9 #include <dos/dosextens.h>
11 #include <intuition/intuition.h>
12 #include <intuition/intuitionbase.h>
13 #include <intuition/classes.h>
14 #include <intuition/classusr.h>
15 #include <intuition/windecorclass.h>
16 #include <intuition/cghooks.h>
17 #include <intuition/icclass.h>
18 #include <intuition/extensions.h>
20 #include <graphics/gfxbase.h>
21 #include <graphics/gfxmacros.h>
23 #include <utility/tagitem.h>
24 #include <utility/hooks.h>
26 #include <clib/macros.h>
28 #include <string.h>
30 #include <proto/exec.h>
31 #include <proto/intuition.h>
32 #include <proto/graphics.h>
33 #include <proto/utility.h>
35 #include <proto/alib.h>
37 #include "intuition_intern.h"
38 #include "gadgets.h"
40 /**************************************************************************************************/
42 #ifdef __AROS__
43 #define USE_AROS_DEFSIZE 1
44 #else
45 #define USE_AROS_DEFSIZE 0
46 #endif
48 #define DEFSIZE_WIDTH 14
49 #define DEFSIZE_HEIGHT 14
51 #define HSPACING 3
52 #define VSPACING 3
53 /* Ralph Schmidt
54 * heuristics for smaller arrows used in apps
55 * like filer
57 #define HSPACING_MIDDLE 2
58 #define VSPACING_MIDDLE 2
59 #define HSPACING_SMALL 1
60 #define VSPACING_SMALL 1
62 #define DRI(dri) ((struct DrawInfo *)(dri))
64 /**************************************************************************************************/
66 static void renderimageframe(struct RastPort *rp, ULONG which, ULONG state, UWORD *pens,
67 WORD left, WORD top, WORD width, WORD height,
68 struct IntuitionBase *IntuitionBase)
70 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
71 WORD right = left + width - 1;
72 WORD bottom = top + height - 1;
73 BOOL leftedgegodown = FALSE;
74 BOOL topedgegoright = FALSE;
76 switch(which)
78 #if 0
79 case CLOSEIMAGE:
80 /* draw separator line at the right side */
81 SetAPen(rp, pens[SHINEPEN]);
82 RectFill(rp, right, top, right, bottom - 1);
83 SetAPen(rp, pens[SHADOWPEN]);
84 WritePixel(rp, right, bottom);
86 right--;
87 break;
89 case ZOOMIMAGE:
90 case DEPTHIMAGE:
91 case SDEPTHIMAGE:
92 /* draw separator line at the left side */
93 SetAPen(rp, pens[SHINEPEN]);
94 WritePixel(rp, left, top);
95 SetAPen(rp, pens[SHADOWPEN]);
96 RectFill(rp, left, top + 1, left, bottom);
98 left++;
99 break;
100 #endif
102 case UPIMAGE:
103 case DOWNIMAGE:
104 leftedgegodown = TRUE;
105 break;
107 case LEFTIMAGE:
108 case RIGHTIMAGE:
109 topedgegoright = TRUE;
110 break;
113 if (left == 0) leftedgegodown = TRUE;
114 if (top == 0) topedgegoright = TRUE;
116 SetAPen(rp, pens[((state == IDS_SELECTED) || (state == IDS_INACTIVESELECTED)) ? SHADOWPEN : SHINEPEN]);
118 /* left edge */
119 RectFill(rp, left,
120 top,
121 left,
122 bottom - (leftedgegodown ? 0 : 1));
124 /* top edge */
125 RectFill(rp, left + 1,
126 top,
127 right - (topedgegoright ? 0 : 1),
128 top);
130 SetAPen(rp, pens[((state == IDS_SELECTED) || (state == IDS_INACTIVESELECTED)) ? SHINEPEN : SHADOWPEN]);
132 /* right edge */
133 RectFill(rp, right,
134 top + (topedgegoright ? 1 : 0),
135 right,
136 bottom);
138 /* bottom edge */
139 RectFill(rp, left + (leftedgegodown ? 1 : 0),
140 bottom,
141 right - 1,
142 bottom);
145 /**************************************************************************************************/
147 static UWORD getbgpen(ULONG state, UWORD *pens)
149 UWORD bg;
150 switch (state)
152 case IDS_NORMAL:
153 case IDS_SELECTED:
154 bg = pens[FILLPEN];
155 break;
157 default:
158 bg = pens[BACKGROUNDPEN];
159 break;
162 return bg;
166 /**************************************************************************************************/
168 IPTR WinDecorClass__OM_NEW(Class *cl, Object *obj, struct opSet *msg)
170 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
171 struct Library *UtilityBase = GetPrivIBase(IntuitionBase)->UtilityBase;
172 struct windecor_data *data;
174 obj = (Object *)DoSuperMethodA(cl, obj, (Msg)msg);
175 if (obj)
177 data = INST_DATA(cl, obj);
178 data->userbuffersize = (ULONG) GetTagData(WDA_UserBuffer, 0, msg->ops_AttrList);
181 return (IPTR)obj;
184 /**************************************************************************************************/
186 IPTR WinDecorClass__OM_GET(Class *cl, Object *obj, struct opGet *msg)
188 struct windecor_data *data = INST_DATA(cl, obj);
190 switch(msg->opg_AttrID)
192 case WDA_UserBuffer:
193 *msg->opg_Storage = (IPTR) data->userbuffersize;
194 break;
195 case WDA_TrueColorOnly:
196 *msg->opg_Storage = FALSE;
197 break;
199 default:
200 return DoSuperMethodA(cl, obj, (Msg)msg);
203 return 1;
207 /**************************************************************************************************/
209 IPTR WinDecorClass__WDM_GETDEFSIZE_SYSIMAGE(Class *cl, Object *obj, struct wdpGetDefSizeSysImage *msg)
211 ULONG def_low_width = DEFSIZE_WIDTH, def_low_height = DEFSIZE_HEIGHT;
212 ULONG def_med_width = DEFSIZE_WIDTH, def_med_height = DEFSIZE_HEIGHT;
213 ULONG def_high_width = DEFSIZE_WIDTH, def_high_height = DEFSIZE_HEIGHT;
215 ULONG refheight = msg->wdp_ReferenceFont->tf_YSize;
216 ULONG refwidth = refheight;
218 switch(msg->wdp_Which)
220 case LEFTIMAGE:
221 case RIGHTIMAGE:
222 #if USE_AROS_DEFSIZE
223 def_low_width = def_med_width = def_high_width = DEFSIZE_WIDTH;
224 def_low_height = def_med_height = def_high_height = DEFSIZE_HEIGHT;
225 #else
226 def_low_width = 16;
227 def_med_width = 16;
228 def_high_width = 23;
229 def_low_height = 11;
230 def_med_height = 10;
231 def_high_height = 22;
232 #endif
233 break;
235 case UPIMAGE:
236 case DOWNIMAGE:
237 #if USE_AROS_DEFSIZE
238 def_low_width = def_med_width = def_high_width = DEFSIZE_WIDTH;
239 def_low_height = def_med_height = def_high_height = DEFSIZE_HEIGHT;
240 #else
241 def_low_width = 13;
242 def_med_width = 18;
243 def_high_width = 23;
244 def_low_height = 11;
245 def_med_height = 11;
246 def_high_height = 22;
247 #endif
248 break;
250 case DEPTHIMAGE:
251 case ZOOMIMAGE:
252 case ICONIFYIMAGE:
253 case LOCKIMAGE:
254 case MUIIMAGE:
255 case POPUPIMAGE:
256 case SNAPSHOTIMAGE:
257 case JUMPIMAGE:
258 #if USE_AROS_DEFSIZE
259 def_low_width = def_med_width = def_high_width = DEFSIZE_WIDTH;
260 def_low_height = def_med_height = def_high_height = DEFSIZE_HEIGHT;
261 #else
262 def_low_width = 18;
263 def_med_width = 24;
264 def_high_width = 24;
265 #endif
266 break;
268 case SDEPTHIMAGE:
269 #if USE_AROS_DEFSIZE
270 def_low_width = def_med_width = def_high_width = DEFSIZE_WIDTH;
271 def_low_height = def_med_height = def_high_height = DEFSIZE_HEIGHT;
272 #else
273 def_low_width = 17;
274 def_med_width = 23;
275 def_high_width = 23;
276 #endif
277 break;
279 case CLOSEIMAGE:
280 #if USE_AROS_DEFSIZE
281 def_low_width = def_med_width = def_high_width = DEFSIZE_WIDTH;
282 def_low_height = def_med_height = def_high_height = DEFSIZE_HEIGHT;
283 #else
284 def_low_width = 15;
285 def_med_width = 20;
286 def_high_width = 20;
287 #endif
288 break;
290 case SIZEIMAGE:
291 #if USE_AROS_DEFSIZE
292 def_low_width = def_med_width = def_high_width = DEFSIZE_WIDTH;
293 def_low_height = def_med_height = def_high_height = DEFSIZE_HEIGHT;
294 #else
295 def_low_width = 13;
296 def_med_width = 18;
297 def_high_width = 18;
298 def_low_height = 11;
299 def_med_height = 10;
300 def_high_height = 10;
301 #endif
302 break;
304 case MENUCHECK:
305 def_low_width =
306 def_med_width =
307 def_high_width = refwidth / 2 + 4; // reffont->tf_XSize * 3 / 2;
308 def_low_height =
309 def_med_height =
310 def_high_height= refheight;
311 break;
313 case MXIMAGE:
314 def_low_width =
315 def_med_width =
316 def_high_width = (refwidth + 1) * 2; // reffont->tf_XSize * 3 - 1;
317 def_low_height =
318 def_med_height =
319 def_high_height= refheight + 1;
320 break;
322 case CHECKIMAGE:
323 def_low_width = (refwidth + 3) * 2;//reffont->tf_XSize * 2;
324 def_low_height = refheight + 3;
325 break;
327 default:
328 return FALSE;
331 switch(msg->wdp_SysiSize)
333 case SYSISIZE_LOWRES:
334 *msg->wdp_Width = def_low_width;
335 *msg->wdp_Height = def_low_height;
336 break;
338 case SYSISIZE_MEDRES:
339 *msg->wdp_Width = def_med_width;
340 *msg->wdp_Height = def_med_height;
341 break;
343 case SYSISIZE_HIRES:
344 default:
345 *msg->wdp_Width = def_high_width;
346 *msg->wdp_Height = def_high_height;
347 break;
350 return TRUE;
353 /**************************************************************************************************/
355 IPTR WinDecorClass__WDM_DRAW_SYSIMAGE(Class *cl, Object *obj, struct wdpDrawSysImage *msg)
357 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
358 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
359 struct RastPort *rp = msg->wdp_RPort;
360 UWORD *pens = DRI(msg->wdp_Dri)->dri_Pens;
361 LONG state = msg->wdp_State;
362 LONG left = msg->wdp_X;
363 LONG top = msg->wdp_Y;
364 LONG width = msg->wdp_Width;
365 LONG height = msg->wdp_Height;
366 LONG right = left + width - 1;
367 LONG bottom = top + height - 1;
368 LONG h_spacing, v_spacing;
370 SetDrMd(rp, JAM1);
372 switch(msg->wdp_Which)
375 case MUIIMAGE:
377 renderimageframe(rp, CLOSEIMAGE, state, pens, left, top, width, height, IntuitionBase);
378 /* no code yet */
379 break;
381 case POPUPIMAGE:
383 renderimageframe(rp, CLOSEIMAGE, state, pens, left, top, width, height, IntuitionBase);
384 /* code should be added later */
385 break;
387 case ICONIFYIMAGE:
389 UWORD bg;
390 WORD h_spacing;
391 WORD v_spacing;
393 renderimageframe(rp, ICONIFYIMAGE, state, pens,
394 left, top, width, height, IntuitionBase);
395 left++;
396 top++;
397 width -= 2;
398 height -= 2;
400 right = left + width - 1;
401 bottom = top + height - 1 ;
402 h_spacing = width / 6;
403 v_spacing = height / 6;
405 bg = getbgpen(state, pens);
407 /* Clear background into correct color */
408 SetAPen(rp, bg);
409 RectFill(rp, left, top, right, bottom);
411 left += h_spacing;
412 right -= h_spacing;
413 top += v_spacing;
414 bottom -= v_spacing;
416 SetAPen(rp, pens[SHADOWPEN]);
417 RectFill(rp, left, top, right, bottom);
419 SetAPen(rp, pens[(state == IDS_SELECTED) ? SHINEPEN :
420 (state == IDS_NORMAL) ? FILLPEN : BACKGROUNDPEN]);
421 RectFill(rp, left + 1, top + 1, right - 1, bottom - 1);
423 right = left + (right - left + 1) / 2;
424 top = top + (bottom - top + 1) / 2;
426 if (right - left < 4) right = left + 4;
428 SetAPen(rp, pens[SHADOWPEN]);
429 RectFill(rp, left, top, right, bottom);
431 left += 2;
432 right -= 2;
433 top += 1;
434 bottom -= 1;
436 SetAPen(rp, pens[(state == IDS_SELECTED) ? FILLPEN :
437 (state == IDS_NORMAL) ? SHINEPEN : BACKGROUNDPEN]);
438 RectFill(rp,left, top, right, bottom);
439 break;
441 case CLOSEIMAGE:
443 renderimageframe(rp, CLOSEIMAGE, state, pens, left, top, width, height, IntuitionBase);
444 left++;
445 top++;
446 width -= 2;
447 height -= 2;
449 right = left + width - 1;
450 bottom = top + height - 1;
451 h_spacing = width * 4 / 10;
452 v_spacing = height * 3 / 10;
454 SetAPen(rp, getbgpen(state, pens));
455 RectFill(rp, left, top, right, bottom);
457 left += h_spacing;
458 right -= h_spacing;
459 top += v_spacing;
460 bottom -= v_spacing;
462 SetAPen(rp, pens[SHADOWPEN]);
463 RectFill(rp, left, top, right, bottom);
465 left++;
466 top++;
467 right--;
468 bottom--;
470 SetAPen(rp, pens[(state == IDS_NORMAL) ? SHINEPEN : BACKGROUNDPEN]);
471 RectFill(rp, left, top, right, bottom);
473 break;
476 case ZOOMIMAGE:
478 UWORD bg;
479 WORD h_spacing;
480 WORD v_spacing;
482 renderimageframe(rp, ZOOMIMAGE, state, pens,
483 left, top, width, height, IntuitionBase);
484 left++;
485 top++;
486 width -= 2;
487 height -= 2;
489 right = left + width - 1;
490 bottom = top + height - 1 ;
491 h_spacing = width / 6;
492 v_spacing = height / 6;
494 bg = getbgpen(state, pens);
496 /* Clear background into correct color */
497 SetAPen(rp, bg);
498 RectFill(rp, left, top, right, bottom);
500 left += h_spacing;
501 right -= h_spacing;
502 top += v_spacing;
503 bottom -= v_spacing;
505 SetAPen(rp, pens[SHADOWPEN]);
506 RectFill(rp, left, top, right, bottom);
508 SetAPen(rp, pens[(state == IDS_SELECTED) ? SHINEPEN :
509 (state == IDS_NORMAL) ? FILLPEN : BACKGROUNDPEN]);
510 RectFill(rp, left + 1, top + 1, right - 1, bottom - 1);
512 right = left + (right - left + 1) / 2;
513 bottom = top + (bottom - top + 1) / 2;
515 if (right - left < 4) right = left + 4;
517 SetAPen(rp, pens[SHADOWPEN]);
518 RectFill(rp, left, top, right, bottom);
520 left += 2;
521 right -= 2;
522 top += 1;
523 bottom -= 1;
525 SetAPen(rp, pens[(state == IDS_SELECTED) ? FILLPEN :
526 (state == IDS_NORMAL) ? SHINEPEN : BACKGROUNDPEN]);
527 RectFill(rp,left, top, right, bottom);
528 break;
531 case DEPTHIMAGE:
533 UWORD bg;
534 WORD h_spacing;
535 WORD v_spacing;
537 renderimageframe(rp, DEPTHIMAGE, state, pens,
538 left, top, width, height, IntuitionBase);
539 left++;
540 top++;
541 right--;
542 bottom--;
543 width -= 2;
544 height -= 2;
546 h_spacing = width / 6;
547 v_spacing = height / 6;
549 bg = getbgpen(state, pens);
551 /* Clear background into correct color */
552 SetAPen(rp, bg);
553 RectFill(rp, left, top, right, bottom);
555 /* Draw a image of two partly overlapped tiny windows,
558 left += h_spacing;
559 top += v_spacing;
561 width -= h_spacing * 2;
562 height -= v_spacing * 2;
564 right = left + width - 1;
565 bottom = top + height - 1;
567 /* Render top left window */
569 SetAPen(rp, pens[SHADOWPEN]);
570 drawrect(rp
571 , left
572 , top
573 , right - (width / 3 )
574 , bottom - (height / 3)
575 , IntuitionBase);
578 /* Fill top left window (inside of the frame above) */
580 if ((state != IDS_INACTIVENORMAL))
582 SetAPen(rp, pens[BACKGROUNDPEN]);
583 RectFill(rp, left + 1, top + 1,
584 right - (width / 3) - 1, bottom - (height / 3) - 1);
588 /* Render bottom right window */
589 SetAPen(rp, pens[SHADOWPEN]);
590 drawrect(rp, left + (width / 3), top + (height / 3),
591 right, bottom, IntuitionBase);
593 /* Fill bottom right window (inside of the frame above) */
594 SetAPen(rp, pens[(state == IDS_INACTIVENORMAL) ? BACKGROUNDPEN : SHINEPEN]);
595 RectFill(rp, left + (width / 3) + 1, top + (height / 3) + 1,
596 right - 1, bottom - 1);
598 if (state == IDS_SELECTED)
600 /* Re-Render top left window */
602 SetAPen(rp, pens[SHADOWPEN]);
603 drawrect(rp, left, top,
604 right - (width / 3 ), bottom - (height / 3), IntuitionBase);
606 break;
609 case SIZEIMAGE:
611 UWORD bg;
612 WORD h_spacing;
613 WORD v_spacing;
614 WORD x, y;
616 renderimageframe(rp, SIZEIMAGE, state, pens,
617 left, top, width, height, IntuitionBase);
618 left++;
619 top++;
620 right--;
621 bottom--;
622 width -= 2;
623 height -= 2;
625 h_spacing = width / 5;
626 v_spacing = height / 5;
628 bg = getbgpen(state, pens);
630 /* Clear background into correct color */
631 SetAPen(rp, bg);
632 RectFill(rp, left, top, right, bottom);
634 /* A triangle image */
636 left += h_spacing;
637 top += v_spacing;
639 right = left + width - 1 - (h_spacing * 2);
640 bottom = top + height - 1 - (v_spacing * 2);
642 width = right - left + 1;
643 height = bottom - top + 1;
645 if (state != IDS_INACTIVENORMAL)
647 SetAPen(rp, pens[SHINEPEN]);
649 for(y = top; y <= bottom; y++)
651 x = left + (bottom - y) * width / height;
652 RectFill(rp, x, y, right, y);
656 SetAPen(rp, pens[SHADOWPEN]);
657 /* Draw triangle border */
658 Move(rp, left, bottom);
659 Draw(rp, right, top);
660 Draw(rp, right, bottom);
661 Draw(rp, left, bottom);
663 break;
666 case LEFTIMAGE:
668 UWORD hspacing,vspacing;
669 WORD cy, i;
671 hspacing = HSPACING;
672 vspacing = VSPACING;
674 if (width <= 12)
676 hspacing = HSPACING_MIDDLE;
679 if (width <= 10)
681 hspacing = HSPACING_SMALL;
684 if (height <= 12)
686 vspacing = VSPACING_MIDDLE;
689 if (height <= 10)
691 vspacing = VSPACING_SMALL;
694 renderimageframe(rp, LEFTIMAGE, state, pens,
695 left, top, width, height, IntuitionBase);
696 left++;
697 top++;
698 right--;
699 bottom--;
700 width -= 2;
701 height -= 2;
703 SetAPen(rp, getbgpen(state, pens));
704 RectFill(rp, left, top, right, bottom);
706 left += hspacing;
707 top += vspacing;
708 width -= hspacing * 2;
709 height -= vspacing * 2;
711 right = left + width - 1;
712 bottom = top + height - 1;
714 cy = (height + 1) / 2;
716 SetAPen(rp, pens[SHADOWPEN]);
718 for(i = 0; i < cy; i++)
720 RectFill(rp, left + (cy - i - 1) * width / cy,
721 top + i,
722 right - i * width / cy / 2,
723 top + i);
724 RectFill(rp, left + (cy - i - 1) * width / cy,
725 bottom - i,
726 right - i * width / cy / 2,
727 bottom - i);
729 break;
732 case UPIMAGE:
734 UWORD hspacing,vspacing;
735 WORD cx, i;
737 hspacing = HSPACING;
738 vspacing = VSPACING;
740 if (width <= 12)
742 hspacing = HSPACING_MIDDLE;
745 if (width <= 10)
747 hspacing = HSPACING_SMALL;
750 if (height <= 12)
752 vspacing = VSPACING_MIDDLE;
755 if (height <= 10)
757 vspacing = VSPACING_SMALL;
760 renderimageframe(rp, UPIMAGE, state, pens,
761 left, top, width, height, IntuitionBase);
762 left++;
763 top++;
764 right--;
765 bottom--;
766 width -= 2;
767 height -= 2;
769 SetAPen(rp, getbgpen(state, pens));
770 RectFill(rp, left, top, right, bottom);
772 left += hspacing;
773 top += vspacing;
774 width -= hspacing * 2;
775 height -= vspacing * 2;
777 right = left + width - 1;
778 bottom = top + height - 1;
780 cx = (width + 1) / 2;
782 SetAPen(rp, pens[SHADOWPEN]);
784 for(i = 0; i < cx; i++)
786 RectFill(rp, left + i,
787 top + (cx - i - 1) * height / cx,
788 left + i,
789 bottom - i * height / cx / 2);
790 RectFill(rp, right - i,
791 top + (cx - i - 1) * height / cx,
792 right - i,
793 bottom - i * height / cx / 2);
796 break;
799 case RIGHTIMAGE:
801 UWORD hspacing,vspacing;
802 WORD cy, i;
804 hspacing = HSPACING;
805 vspacing = VSPACING;
807 if (width <= 12)
809 hspacing = HSPACING_MIDDLE;
812 if (width <= 10)
814 hspacing = HSPACING_SMALL;
817 if (height <= 12)
819 vspacing = VSPACING_MIDDLE;
822 if (height <= 10)
824 vspacing = VSPACING_SMALL;
827 renderimageframe(rp, RIGHTIMAGE, state, pens,
828 left, top, width, height, IntuitionBase);
829 left++;
830 top++;
831 right--;
832 bottom--;
833 width -= 2;
834 height -= 2;
837 SetAPen(rp, getbgpen(state, pens));
838 RectFill(rp, left, top, right, bottom);
840 left += hspacing;
841 top += vspacing;
842 width -= hspacing * 2;
843 height -= vspacing * 2;
845 right = left + width - 1;
846 bottom = top + height - 1;
848 cy = (height + 1) / 2;
850 SetAPen(rp, pens[SHADOWPEN]);
852 for(i = 0; i < cy; i++)
854 RectFill(rp, left + i * width / cy / 2,
855 top + i,
856 right - (cy - i - 1) * width / cy,
857 top + i);
858 RectFill(rp, left + i * width / cy / 2,
859 bottom - i,
860 right - (cy - i - 1) * width / cy,
861 bottom - i);
863 break;
866 case DOWNIMAGE:
868 UWORD hspacing,vspacing;
869 WORD cx, i;
871 hspacing = HSPACING;
872 vspacing = VSPACING;
874 if (width <= 12)
876 hspacing = HSPACING_MIDDLE;
879 if (width <= 10)
881 hspacing = HSPACING_SMALL;
884 if (height <= 12)
886 vspacing = VSPACING_MIDDLE;
889 if (height <= 10)
891 vspacing = VSPACING_SMALL;
894 renderimageframe(rp, DOWNIMAGE, state, pens,
895 left, top, width, height, IntuitionBase);
896 left++;
897 top++;
898 right--;
899 bottom--;
900 width -= 2;
901 height -= 2;
903 SetAPen(rp, getbgpen(state, pens));
904 RectFill(rp, left, top, right, bottom);
906 left += hspacing;
907 top += vspacing;
908 width -= hspacing * 2;
909 height -= vspacing * 2;
911 right = left + width - 1;
912 bottom = top + height - 1;
914 cx = (width + 1) / 2;
916 SetAPen(rp, pens[SHADOWPEN]);
918 for(i = 0; i < cx; i++)
920 RectFill(rp, left + i,
921 top + i * height / cx / 2,
922 left + i,
923 bottom - (cx - i - 1) * height / cx);
924 RectFill(rp, right - i,
925 top + i * height / cx / 2,
926 right - i,
927 bottom - (cx - i - 1) * height / cx);
930 break;
934 default:
935 return FALSE;
938 return TRUE;
941 /**************************************************************************************************/
943 static void findtitlearea(struct Window *win, LONG *left, LONG *right)
945 struct Gadget *g;
947 *left = 0;
948 *right = win->Width - 1;
950 for (g = win->FirstGadget; g; g = g->NextGadget)
952 if (g->Activation & GACT_TOPBORDER && g != (struct Gadget *)IW(win)->sysgads[DRAGBAR])
954 if (!(g->Flags & GFLG_RELRIGHT))
956 if (g->LeftEdge + g->Width > *left)
957 *left = g->LeftEdge + g->Width;
959 else
961 if (g->LeftEdge + win->Width - 1 - 1 < *right)
962 *right = g->LeftEdge + win->Width - 1 - 1;
969 /**************************************************************************************************/
971 IPTR INTERNAL_WDM_DRAW_WINTITLE(Class *cl, Object *obj, struct wdpDrawWinBorder *msg)
973 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
974 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
975 struct RastPort *rp = msg->wdp_RPort;
976 struct Window *window = msg->wdp_Window;
977 UWORD *pens = DRI(msg->wdp_Dri)->dri_Pens;
978 LONG right, left;
980 findtitlearea(window, &left, &right);
982 SetDrMd(rp, JAM1);
983 SetAPen(rp, pens[(window->Flags & WFLG_WINDOWACTIVE) ? FILLPEN : BACKGROUNDPEN]);
984 CheckRectFill(rp, left + 1, 1, right - 1, window->BorderTop - 2, IntuitionBase);
986 if (right - left > 6)
988 ULONG textlen, titlelen;
989 struct TextExtent te;
991 SetFont(rp, DRI(msg->wdp_Dri)->dri_Font);
993 titlelen = strlen(window->Title);
994 textlen = TextFit(rp
995 , window->Title
996 , titlelen
997 , &te
998 , NULL
1000 , right - left - 6
1001 , window->BorderTop - 2);
1002 if (textlen)
1004 left = left + 3;
1006 SetAPen(rp, pens[(window->Flags & WFLG_WINDOWACTIVE) ? FILLTEXTPEN : TEXTPEN]);
1008 Move(rp, left, DRI(msg->wdp_Dri)->dri_Font->tf_Baseline + 2);
1009 Text(rp, window->Title, textlen);
1013 return TRUE;
1016 /**************************************************************************************************/
1018 IPTR WinDecorClass__WDM_DRAW_WINBORDER(Class *cl, Object *obj, struct wdpDrawWinBorder *msg)
1020 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
1021 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1022 struct RastPort *rp = msg->wdp_RPort;
1023 struct Window *window = msg->wdp_Window;
1024 UWORD *pens = DRI(msg->wdp_Dri)->dri_Pens;
1025 LONG left, right;
1027 SetDrMd(rp, JAM1);
1028 SetAPen(rp, pens[SHINEPEN]);
1030 if (window->BorderTop > 0)
1032 /* Outer shine edge on top side */
1034 CheckRectFill(rp, 0, 0, window->Width - 1, 0, IntuitionBase);
1037 if (!(msg->wdp_Flags & WDF_DWB_TOP_ONLY))
1039 if (window->BorderLeft > 0)
1041 /* Outer shine edge on left side */
1043 CheckRectFill(rp, 0, 0, 0, window->Height - 1, IntuitionBase);
1046 if (window->BorderRight > 1)
1048 /* Inner shine edge on right side */
1050 CheckRectFill(rp,
1051 window->Width - window->BorderRight, window->BorderTop,
1052 window->Width - window->BorderRight, window->Height - window->BorderBottom,
1053 IntuitionBase);
1056 if (window->BorderBottom > 1)
1058 /* Inner shine edge on bottom side */
1060 CheckRectFill(rp,
1061 window->BorderLeft, window->Height - window->BorderBottom,
1062 window->Width - window->BorderRight, window->Height - window->BorderBottom,
1063 IntuitionBase);
1067 SetAPen(rp, pens[SHADOWPEN]);
1069 if (!(msg->wdp_Flags & WDF_DWB_TOP_ONLY))
1071 if (window->BorderRight > 0)
1073 /* Outer shadow edge on right side */
1075 CheckRectFill(rp, window->Width - 1, 1,
1076 window->Width - 1, window->Height - 1, IntuitionBase);
1079 if (window->BorderBottom > 0)
1081 /* Outer shadow edge on bottom side */
1083 CheckRectFill(rp, 1, window->Height - 1,
1084 window->Width - 1, window->Height - 1, IntuitionBase);
1087 if (window->BorderLeft > 1)
1089 /* Inner shadow edge on left side */
1091 CheckRectFill(rp, window->BorderLeft - 1, window->BorderTop - 1,
1092 window->BorderLeft - 1, window->Height - window->BorderBottom,
1093 IntuitionBase);
1098 if (window->BorderTop > 1)
1100 /* Inner shadow edge on top side */
1102 CheckRectFill(rp, window->BorderLeft - 1, window->BorderTop - 1,
1103 window->Width - window->BorderRight, window->BorderTop - 1,
1104 IntuitionBase);
1107 SetAPen(rp, pens[(window->Flags & WFLG_WINDOWACTIVE) ? FILLPEN : BACKGROUNDPEN]);
1109 if (window->BorderTop > 2)
1111 /* Fill on top side */
1113 CheckRectFill(rp, 1, 1, window->Width - 2, window->BorderTop - 2, IntuitionBase);
1116 if (!(msg->wdp_Flags & WDF_DWB_TOP_ONLY))
1118 if (window->BorderLeft > 2)
1120 /* Fill on left side */
1122 CheckRectFill(rp, 1, 1, window->BorderLeft - 2, window->Height - 2, IntuitionBase);
1126 if (window->BorderRight > 2)
1128 /* Fill on right side */
1130 CheckRectFill(rp, window->Width - window->BorderRight + 1, 1,
1131 window->Width - 2, window->Height - 2, IntuitionBase);
1134 if (window->BorderBottom > 2)
1136 /* Fill on bottom side */
1138 CheckRectFill(rp, 1, window->Height - window->BorderBottom + 1,
1139 window->Width - 2, window->Height - 2, IntuitionBase);
1143 findtitlearea(window, &left, &right);
1145 if (left != 0)
1147 /* Left edge of title area */
1149 SetAPen(rp, pens[SHINEPEN]);
1150 Move(rp, left, 1);
1151 Draw(rp, left, window->BorderTop - 2);
1154 if (right != window->Width - 1)
1156 /* Right edges of title area */
1158 SetAPen(rp, pens[SHADOWPEN]);
1159 Move(rp, right, 1);
1160 Draw(rp, right, window->BorderTop - 2);
1163 if (window->Title) INTERNAL_WDM_DRAW_WINTITLE(cl, obj, msg);
1165 return TRUE;
1168 /**************************************************************************************************/
1170 IPTR WinDecorClass__WDM_LAYOUT_BORDERGADGETS(Class *cl, Object *obj, struct wdpLayoutBorderGadgets *msg)
1172 struct Gadget *gadget = msg->wdp_Gadgets;
1174 if (!(msg->wdp_Flags & WDF_LBG_SYSTEMGADGET)) return TRUE;
1176 while(gadget)
1178 switch(gadget->GadgetType & GTYP_SYSTYPEMASK)
1180 case GTYP_CLOSE:
1181 gadget->LeftEdge = 0;
1182 gadget->Width = gadget->Height;
1183 gadget->Flags &= ~(GFLG_RELRIGHT | GFLG_RELWIDTH);
1184 break;
1186 case GTYP_WDEPTH:
1187 gadget->LeftEdge = -gadget->Height + 1;
1188 gadget->Width = gadget->Height;
1189 gadget->Flags &= ~GFLG_RELWIDTH;
1190 gadget->Flags |= GFLG_RELRIGHT;
1191 break;
1193 case GTYP_WZOOM:
1194 gadget->LeftEdge = -gadget->Height * 2 + 1;
1195 gadget->Width = gadget->Height;
1196 gadget->Flags &= ~GFLG_RELWIDTH;
1197 gadget->Flags |= GFLG_RELRIGHT;
1198 break;
1200 case GTYP_WDRAGGING:
1201 gadget->LeftEdge = 0;
1202 gadget->Width = 0;
1203 gadget->Flags &= ~GFLG_RELRIGHT;
1204 gadget->Flags |= GFLG_RELWIDTH;
1205 break;
1208 if (gadget->GadgetType == GTYP_CUSTOMGADGET)
1210 switch(gadget->GadgetID)
1212 case ETI_Iconify:
1213 gadget->LeftEdge = -gadget->Height * 3 + 1;
1214 gadget->Width = gadget->Height;
1215 gadget->Flags &= ~GFLG_RELWIDTH;
1216 gadget->Flags |= GFLG_RELRIGHT;
1217 break;
1221 if (msg->wdp_Flags & WDF_LBG_MULTIPLE)
1223 gadget = gadget->NextGadget;
1225 else
1227 gadget = NULL;
1231 return TRUE;
1234 /**************************************************************************************************/
1236 IPTR WinDecorClass__WDM_DRAW_BORDERPROPBACK(Class *cl, Object *obj, struct wdpDrawBorderPropBack *msg)
1238 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
1239 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1240 struct Window *window = msg->wdp_Window;
1241 struct RastPort *rp = msg->wdp_RPort;
1242 struct Gadget *gadget = msg->wdp_Gadget;
1243 struct Rectangle *r = msg->wdp_RenderRect;
1244 struct PropInfo *pi = ((struct PropInfo *)gadget->SpecialInfo);
1245 UWORD *pens = DRI(msg->wdp_Dri)->dri_Pens;
1247 SetDrMd(rp, JAM2);
1249 if (pi->Flags & PROPNEWLOOK)
1251 static CONST UWORD pattern[] = {0x5555,0xAAAA};
1253 SetAfPt(rp, pattern, 1);
1254 SetAPen(rp, pens[SHADOWPEN]);
1255 SetBPen(rp, pens[(window->Flags & WFLG_WINDOWACTIVE) ? FILLPEN : BACKGROUNDPEN]);
1256 RectFill(rp, r->MinX, r->MinY, r->MaxX, r->MaxY);
1257 SetAfPt(rp, NULL, 0);
1259 else
1261 SetAPen(rp, pens[BACKGROUNDPEN]);
1262 RectFill(rp, r->MinX, r->MinY, r->MaxX, r->MaxY);
1265 return TRUE;
1268 /**************************************************************************************************/
1270 IPTR WinDecorClass__WDM_DRAW_BORDERPROPKNOB(Class *cl, Object *obj, struct wdpDrawBorderPropKnob *msg)
1272 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
1273 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1274 struct Window *window = msg->wdp_Window;
1275 struct RastPort *rp = msg->wdp_RPort;
1276 struct Gadget *gadget = msg->wdp_Gadget;
1277 struct Rectangle *r = msg->wdp_RenderRect;
1278 struct PropInfo *pi = ((struct PropInfo *)gadget->SpecialInfo);
1279 UWORD *pens = DRI(msg->wdp_Dri)->dri_Pens;
1281 SetDrMd(rp, JAM2);
1283 if (pi->Flags & PROPBORDERLESS)
1285 SetAPen(rp, pens[SHINEPEN]);
1287 /* Top edge */
1288 RectFill(rp, r->MinX, r->MinY, r->MaxX - 1, r->MinY);
1290 /* Left edge */
1291 RectFill(rp, r->MinX, r->MinY + 1, r->MinX, r->MaxY - 1);
1293 SetAPen(rp, pens[SHADOWPEN]);
1295 /* Right edge */
1296 RectFill(rp, r->MaxX, r->MinY, r->MaxX, r->MaxY);
1298 /* Bottom edge */
1299 RectFill(rp, r->MinX, r->MaxY, r->MaxX - 1, r->MaxY);
1301 r->MinX++;
1302 r->MinY++;
1303 r->MaxX--;
1304 r->MaxY--;
1306 } /* PROPBORDERLESS */
1307 else
1309 SetAPen(rp, pens[SHADOWPEN]);
1311 if (pi->Flags & FREEHORIZ)
1313 /* black line at the left and at the right */
1315 RectFill(rp, r->MinX, r->MinY, r->MinX, r->MaxY);
1316 RectFill(rp, r->MaxX, r->MinY, r->MaxX, r->MaxY);
1318 r->MinX++;
1319 r->MaxX--;
1323 if (pi->Flags & FREEVERT)
1325 /* black line at the top and at the bottom */
1327 RectFill(rp, r->MinX, r->MinY, r->MaxX, r->MinY);
1328 RectFill(rp, r->MinX, r->MaxY, r->MaxX, r->MaxY);
1330 r->MinY++,
1331 r->MaxY--;
1335 } /* not PROPBORDERLESS */
1338 SetAPen(rp, pens[(window->Flags & WFLG_WINDOWACTIVE) ? FILLPEN : BACKGROUNDPEN]);
1340 /* interior */
1341 RectFill(rp, r->MinX, r->MinY, r->MaxX, r->MaxY);
1343 return TRUE;
1347 /**************************************************************************************************/
1349 IPTR WinDecorClass__WDM_INITWINDOW(Class *cl, Object *obj, struct wdpInitWindow *msg)
1351 return TRUE;
1354 /**************************************************************************************************/
1356 IPTR WinDecorClass__WDM_EXITWINDOW(Class *cl, Object *obj, struct wdpExitWindow *msg)
1358 return TRUE;
1361 /**************************************************************************************************/
1363 IPTR WinDecorClass__WDM_WINDOWSHAPE(Class *cl, Object *obj, struct wdpWindowShape *msg)
1365 return 0;