Support rastport clipping rectangle for layerless rastports
[tangerine.git] / test / windecor.c
bloba1f89e3f6fc906ad24ea8216684bed46c7f721b6
1 #include <dos/dos.h>
2 #include <intuition/classusr.h>
3 #include <intuition/windecorclass.h>
4 #include <intuition/scrdecorclass.h>
5 #include <graphics/rpattr.h>
6 #include <graphics/gfxmacros.h>
7 #include <utility/tagitem.h>
9 #include <proto/exec.h>
10 #include <proto/graphics.h>
11 #include <proto/layers.h>
12 #include <proto/intuition.h>
13 #include <proto/utility.h>
14 #include <proto/cybergraphics.h>
15 #include <clib/alib_protos.h>
17 #include <stdio.h>
19 #include <aros/debug.h>
21 /**************************************************************************************************/
23 struct IClass *cl, *scrcl;
24 Object *thisdecorobj, *olddecorobj;
25 Object *thisscrdecorobj, *oldscrdecorobj;
26 struct Screen *scr;
27 struct DrawInfo *dri;
29 #define ACTIVE_1 0x6c7be9
30 #define ACTIVE_2 0x00006e
31 #define INACTIVE_1 0xeeeeee
32 #define INACTIVE_2 0x888888
34 /**************************************************************************************************/
36 struct windecor_data
38 struct DrawInfo *dri;
39 struct Screen *scr;
42 /**************************************************************************************************/
44 static void CheckRectFill(struct RastPort *rp, LONG x1, LONG y1, LONG x2, LONG y2)
46 ULONG fgcolor;
47 ULONG bgcolor;
48 LONG y;
50 if ((x2 < x1) || (y2 < y1)) return;
52 GetRPAttrs(rp, RPTAG_FgColor, &fgcolor, RPTAG_BgColor, &bgcolor, TAG_DONE);
54 if ((fgcolor == bgcolor) || (y1 == y2))
56 RectFill(rp, x1, y1, x2, y2);
58 else
60 LONG r1 = (fgcolor >> 16) & 0xFF;
61 LONG g1 = (fgcolor >> 8) & 0xFF;
62 LONG b1 = fgcolor & 0xFF;
63 LONG r2 = (bgcolor >> 16) & 0xFF;
64 LONG g2 = (bgcolor >> 8) & 0xFF;
65 LONG b2 = bgcolor & 0xFF;
67 for(y = y1; y <= y2; y++)
69 LONG r, g, b, rgb;
70 LONG mul = (y - y1);
71 LONG div = (y2 - y1);
73 r = r1 + (r2 - r1) * mul / div;
74 g = g1 + (g2 - g1) * mul / div;
75 b = b1 + (b2 - b1) * mul / div;
77 rgb = (r << 16) + (g << 8) + b;
79 SetRPAttrs(rp, RPTAG_FgColor, rgb, TAG_DONE);
80 RectFill(rp, x1, y, x2, y);
84 SetRPAttrs(rp, RPTAG_FgColor, fgcolor, TAG_DONE);
89 /**************************************************************************************************/
91 static IPTR windecor_new(Class *cl, Object *obj, struct opSet *msg)
93 struct windecor_data *data;
95 obj = (Object *)DoSuperMethodA(cl, obj, (Msg)msg);
96 if (obj)
98 data = INST_DATA(cl, obj);
100 data->dri = (struct DrawInfo *)GetTagData(WDA_DrawInfo, 0, msg->ops_AttrList);
101 data->scr = (struct Screen *)GetTagData(WDA_Screen, 0, msg->ops_AttrList);
103 if (!data->dri || !data->scr)
105 STACKULONG method = OM_DISPOSE;
107 CoerceMethodA(cl, obj, (Msg)&method);
109 return 0;
114 return (IPTR)obj;
117 /**************************************************************************************************/
119 static IPTR windecor_get(Class *cl, Object *obj, struct opGet *msg)
121 //struct windecor_data *data = INST_DATA(cl, obj);
123 switch(msg->opg_AttrID)
125 case WDA_TrueColorOnly:
126 *msg->opg_Storage = TRUE;
127 break;
129 default:
130 return DoSuperMethodA(cl, obj, (Msg)msg);
133 return 1;
137 /**************************************************************************************************/
139 #define HSPACING 3
140 #define VSPACING 3
141 #define HSPACING_MIDDLE 2
142 #define VSPACING_MIDDLE 2
143 #define HSPACING_SMALL 1
144 #define VSPACING_SMALL 1
146 static void renderimageframe(struct RastPort *rp, ULONG which, ULONG state, UWORD *pens,
147 WORD left, WORD top, WORD width, WORD height)
149 WORD right = left + width - 1;
150 WORD bottom = top + height - 1;
152 SetAPen(rp, pens[SHADOWPEN]);
154 left--;top--;
155 right++;bottom++;
157 /* left edge */
158 RectFill(rp, left,
159 top,
160 left,
161 bottom);
163 /* top edge */
164 RectFill(rp, left + 1,
165 top,
166 right,
167 top);
169 SetAPen(rp, pens[SHINEPEN]);
171 /* right edge */
172 RectFill(rp, right,
173 top + 1,
174 right,
175 bottom);
177 /* bottom edge */
178 RectFill(rp, left + 1,
179 bottom,
180 right - 1,
181 bottom);
183 left++;top++;
184 right--;bottom--;
186 SetAPen(rp, pens[((state == IDS_SELECTED) || (state == IDS_INACTIVESELECTED)) ? SHADOWPEN : SHINEPEN]);
188 /* left edge */
189 RectFill(rp, left,
190 top,
191 left,
192 bottom);
194 /* top edge */
195 RectFill(rp, left + 1,
196 top,
197 right,
198 top);
200 SetAPen(rp, pens[((state == IDS_SELECTED) || (state == IDS_INACTIVESELECTED)) ? SHINEPEN : SHADOWPEN]);
202 /* right edge */
203 RectFill(rp, right,
204 top + 1,
205 right,
206 bottom);
208 /* bottom edge */
209 RectFill(rp, left + 1,
210 bottom,
211 right - 1,
212 bottom);
215 /**************************************************************************************************/
217 static UWORD getbgpen(ULONG state, UWORD *pens)
219 UWORD bg;
221 switch (state)
223 case IDS_NORMAL:
224 case IDS_SELECTED:
225 bg = pens[FILLPEN];
226 break;
228 default:
229 bg = pens[BACKGROUNDPEN];
230 break;
233 return bg;
236 /**************************************************************************************************/
238 static void drawrect(struct RastPort *rp, WORD x1, WORD y1, WORD x2, WORD y2)
240 Move(rp, x1, y1);
242 /* We RectFill() because it is generally faster than Draw()
243 (Draw() uses Set/GetPixel() while RectFill() can do higherlevel
244 clipping. Also it is MUCH faster in the x11gfx hidd.
247 RectFill(rp, x1, y1, x2 - 1, y1); /* Top */
248 RectFill(rp, x2, y1, x2, y2 - 1); /* Right */
249 RectFill(rp, x1 + 1, y2, x2, y2); /* Bottom */
250 RectFill(rp, x1, y1 + 1, x1, y2); /* Left */
252 return;
255 /**************************************************************************************************/
257 IPTR windecor_draw_sysimage(Class *cl, Object *obj, struct wdpDrawSysImage *msg)
259 struct windecor_data *data = INST_DATA(cl, obj);
260 struct RastPort *rp = msg->wdp_RPort;
261 UWORD *pens = data->dri->dri_Pens;
262 LONG state = msg->wdp_State;
263 LONG left = msg->wdp_X;
264 LONG top = msg->wdp_Y;
265 LONG width = msg->wdp_Width;
266 LONG height = msg->wdp_Height;
267 LONG right = left + width - 1;
268 LONG bottom = top + height - 1;
269 LONG h_spacing, v_spacing;
271 SetDrMd(rp, JAM1);
273 switch(msg->wdp_Which)
275 case CLOSEIMAGE:
277 left += 3; top += 3;
278 right -= 3; bottom -= 3;
279 width -= 6; height -= 6;
281 renderimageframe(rp, CLOSEIMAGE, state, pens, left, top, width, height);
282 left++;
283 top++;
284 width -= 2;
285 height -= 2;
287 right = left + width - 1;
288 bottom = top + height - 1;
289 h_spacing = width * 4 / 10;
290 v_spacing = height * 3 / 10;
292 #if 0
293 SetAPen(rp, getbgpen(state, pens));
294 RectFill(rp, left, top, right, bottom);
295 #endif
296 left += h_spacing;
297 right -= h_spacing;
298 top += v_spacing;
299 bottom -= v_spacing;
301 SetAPen(rp, pens[SHADOWPEN]);
302 RectFill(rp, left, top, right, bottom);
304 left++;
305 top++;
306 right--;
307 bottom--;
309 SetAPen(rp, pens[(state == IDS_NORMAL) ? SHINEPEN : BACKGROUNDPEN]);
310 RectFill(rp, left, top, right, bottom);
312 break;
315 case ZOOMIMAGE:
317 UWORD bg;
318 WORD h_spacing;
319 WORD v_spacing;
321 left += 3; top += 3;
322 right -= 3; bottom -= 3;
323 width -= 6; height -= 6;
325 renderimageframe(rp, ZOOMIMAGE, state, pens,
326 left, top, width, height);
327 left++;
328 top++;
329 width -= 2;
330 height -= 2;
332 right = left + width - 1;
333 bottom = top + height - 1 ;
334 h_spacing = width / 6;
335 v_spacing = height / 6;
337 bg = getbgpen(state, pens);
339 #if 0
340 /* Clear background into correct color */
341 SetAPen(rp, bg);
342 RectFill(rp, left, top, right, bottom);
343 #endif
345 left += h_spacing;
346 right -= h_spacing;
347 top += v_spacing;
348 bottom -= v_spacing;
350 SetAPen(rp, pens[SHADOWPEN]);
351 RectFill(rp, left, top, right, bottom);
353 SetAPen(rp, pens[(state == IDS_SELECTED) ? SHINEPEN :
354 (state == IDS_NORMAL) ? FILLPEN : BACKGROUNDPEN]);
355 RectFill(rp, left + 1, top + 1, right - 1, bottom - 1);
357 right = left + (right - left + 1) / 2;
358 bottom = top + (bottom - top + 1) / 2;
360 if (right - left < 4) right = left + 4;
362 SetAPen(rp, pens[SHADOWPEN]);
363 RectFill(rp, left, top, right, bottom);
365 left += 2;
366 right -= 2;
367 top += 1;
368 bottom -= 1;
370 SetAPen(rp, pens[(state == IDS_SELECTED) ? FILLPEN :
371 (state == IDS_NORMAL) ? SHINEPEN : BACKGROUNDPEN]);
372 RectFill(rp,left, top, right, bottom);
373 break;
376 case DEPTHIMAGE:
378 UWORD bg;
379 WORD h_spacing;
380 WORD v_spacing;
382 left += 3; top += 3;
383 right -= 3; bottom -= 3;
384 width -= 6; height -= 6;
386 renderimageframe(rp, DEPTHIMAGE, state, pens,
387 left, top, width, height);
388 left++;
389 top++;
390 right--;
391 bottom--;
392 width -= 2;
393 height -= 2;
395 h_spacing = width / 6;
396 v_spacing = height / 6;
398 bg = getbgpen(state, pens);
400 #if 0
401 /* Clear background into correct color */
402 SetAPen(rp, bg);
403 RectFill(rp, left, top, right, bottom);
404 #endif
406 /* Draw a image of two partly overlapped tiny windows,
409 left += h_spacing;
410 top += v_spacing;
412 width -= h_spacing * 2;
413 height -= v_spacing * 2;
415 right = left + width - 1;
416 bottom = top + height - 1;
418 /* Render top left window */
420 SetAPen(rp, pens[SHADOWPEN]);
421 drawrect(rp
422 , left
423 , top
424 , right - (width / 3 )
425 , bottom - (height / 3));
428 /* Fill top left window (inside of the frame above) */
430 if ((state != IDS_INACTIVENORMAL))
432 SetAPen(rp, pens[BACKGROUNDPEN]);
433 RectFill(rp, left + 1, top + 1,
434 right - (width / 3) - 1, bottom - (height / 3) - 1);
438 /* Render bottom right window */
439 SetAPen(rp, pens[SHADOWPEN]);
440 drawrect(rp, left + (width / 3), top + (height / 3),
441 right, bottom);
443 /* Fill bottom right window (inside of the frame above) */
444 SetAPen(rp, pens[(state == IDS_INACTIVENORMAL) ? BACKGROUNDPEN : SHINEPEN]);
445 RectFill(rp, left + (width / 3) + 1, top + (height / 3) + 1,
446 right - 1, bottom - 1);
448 if (state == IDS_SELECTED)
450 /* Re-Render top left window */
452 SetAPen(rp, pens[SHADOWPEN]);
453 drawrect(rp, left, top,
454 right - (width / 3 ), bottom - (height / 3));
456 break;
459 case SIZEIMAGE:
461 UWORD bg;
462 WORD h_spacing;
463 WORD v_spacing;
464 WORD x, y;
466 #if 0
467 renderimageframe(rp, SIZEIMAGE, state, pens,
468 left, top, width, height);
469 #endif
470 left++;
471 top++;
472 right--;
473 bottom--;
474 width -= 2;
475 height -= 2;
477 h_spacing = width / 5;
478 v_spacing = height / 5;
480 bg = getbgpen(state, pens);
482 #if 0
483 /* Clear background into correct color */
484 SetAPen(rp, bg);
485 RectFill(rp, left, top, right, bottom);
486 #endif
488 /* A triangle image */
490 left += h_spacing;
491 top += v_spacing;
493 right = left + width - 1 - (h_spacing * 2);
494 bottom = top + height - 1 - (v_spacing * 2);
496 width = right - left + 1;
497 height = bottom - top + 1;
499 if (state != IDS_INACTIVENORMAL)
501 SetAPen(rp, pens[state == IDS_SELECTED ? BACKGROUNDPEN : SHINEPEN]);
503 for(y = top; y <= bottom; y++)
505 x = left + (bottom - y) * width / height;
506 RectFill(rp, x, y, right, y);
510 SetAPen(rp, pens[SHADOWPEN]);
511 /* Draw triangle border */
512 Move(rp, left, bottom);
513 Draw(rp, right, top);
514 Draw(rp, right, bottom);
515 Draw(rp, left, bottom);
517 break;
520 case LEFTIMAGE:
522 UWORD hspacing,vspacing;
523 WORD cy, i, j;
525 hspacing = HSPACING;
526 vspacing = VSPACING;
528 if (width <= 12)
530 hspacing = HSPACING_MIDDLE;
533 if (width <= 10)
535 hspacing = HSPACING_SMALL;
538 if (height <= 12)
540 vspacing = VSPACING_MIDDLE;
543 if (height <= 10)
545 vspacing = VSPACING_SMALL;
548 #if 0
549 renderimageframe(rp, LEFTIMAGE, state, pens,
550 left, top, width, height);
551 #endif
553 left++;
554 top++;
555 right--;
556 bottom--;
557 width -= 2;
558 height -= 2;
560 #if 0
561 SetAPen(rp, getbgpen(state, pens));
562 RectFill(rp, left, top, right, bottom);
563 #endif
565 left += hspacing;
566 top += vspacing;
567 width -= hspacing * 2;
568 height -= vspacing * 2;
570 right = left + width - 1;
571 bottom = top + height - 1;
573 cy = (height + 1) / 2;
575 SetAPen(rp, pens[SHADOWPEN]);
577 for(j = 0; j < 2; j++)
579 for(i = 0; i < cy; i++)
581 RectFill(rp, 1 - j + left + (cy - i - 1) * width / cy,
582 1 - j + top + i,
583 1 - j + right - i * width / cy / 2,
584 1 - j + top + i);
585 RectFill(rp, 1 - j + left + (cy - i - 1) * width / cy,
586 1 - j + bottom - i,
587 1 - j + right - i * width / cy / 2,
588 1 - j + bottom - i);
591 SetAPen(rp, pens[state == IDS_SELECTED ? BACKGROUNDPEN : SHINEPEN]);
593 break;
596 case UPIMAGE:
598 UWORD hspacing,vspacing;
599 WORD cx, i, j;
601 hspacing = HSPACING;
602 vspacing = VSPACING;
604 if (width <= 12)
606 hspacing = HSPACING_MIDDLE;
609 if (width <= 10)
611 hspacing = HSPACING_SMALL;
614 if (height <= 12)
616 vspacing = VSPACING_MIDDLE;
619 if (height <= 10)
621 vspacing = VSPACING_SMALL;
624 #if 0
625 renderimageframe(rp, UPIMAGE, state, pens,
626 left, top, width, height);
627 #endif
629 left++;
630 top++;
631 right--;
632 bottom--;
633 width -= 2;
634 height -= 2;
636 #if 0
637 SetAPen(rp, getbgpen(state, pens));
638 RectFill(rp, left, top, right, bottom);
639 #endif
641 left += hspacing;
642 top += vspacing;
643 width -= hspacing * 2;
644 height -= vspacing * 2;
646 right = left + width - 1;
647 bottom = top + height - 1;
649 cx = (width + 1) / 2;
651 SetAPen(rp, pens[SHADOWPEN]);
653 for(j = 0; j < 2; j++)
655 for(i = 0; i < cx; i++)
657 RectFill(rp, 1 - j + left + i,
658 1 - j + top + (cx - i - 1) * height / cx,
659 1 - j + left + i,
660 1 - j + bottom - i * height / cx / 2);
661 RectFill(rp, 1 - j + right - i,
662 1 - j + top + (cx - i - 1) * height / cx,
663 1 - j + right - i,
664 1 - j + bottom - i * height / cx / 2);
666 SetAPen(rp, pens[state == IDS_SELECTED ? BACKGROUNDPEN : SHINEPEN]);
668 break;
671 case RIGHTIMAGE:
673 UWORD hspacing,vspacing;
674 WORD cy, i, j;
676 hspacing = HSPACING;
677 vspacing = VSPACING;
679 if (width <= 12)
681 hspacing = HSPACING_MIDDLE;
684 if (width <= 10)
686 hspacing = HSPACING_SMALL;
689 if (height <= 12)
691 vspacing = VSPACING_MIDDLE;
694 if (height <= 10)
696 vspacing = VSPACING_SMALL;
699 #if 0
700 renderimageframe(rp, RIGHTIMAGE, state, pens,
701 left, top, width, height);
702 #endif
704 left++;
705 top++;
706 right--;
707 bottom--;
708 width -= 2;
709 height -= 2;
712 #if 0
713 SetAPen(rp, getbgpen(state, pens));
714 RectFill(rp, left, top, right, bottom);
715 #endif
717 left += hspacing;
718 top += vspacing;
719 width -= hspacing * 2;
720 height -= vspacing * 2;
722 right = left + width - 1;
723 bottom = top + height - 1;
725 cy = (height + 1) / 2;
727 SetAPen(rp, pens[SHADOWPEN]);
729 for(j = 0; j < 2; j++)
731 for(i = 0; i < cy; i++)
733 RectFill(rp, 1 - j + left + i * width / cy / 2,
734 1 - j + top + i,
735 1 - j + right - (cy - i - 1) * width / cy,
736 1 - j + top + i);
737 RectFill(rp, 1 - j + left + i * width / cy / 2,
738 1 - j + bottom - i,
739 1 - j + right - (cy - i - 1) * width / cy,
740 1 - j + bottom - i);
742 SetAPen(rp, pens[state == IDS_SELECTED ? BACKGROUNDPEN : SHINEPEN]);
744 break;
747 case DOWNIMAGE:
749 UWORD hspacing,vspacing;
750 WORD cx, i, j;
752 hspacing = HSPACING;
753 vspacing = VSPACING;
755 if (width <= 12)
757 hspacing = HSPACING_MIDDLE;
760 if (width <= 10)
762 hspacing = HSPACING_SMALL;
765 if (height <= 12)
767 vspacing = VSPACING_MIDDLE;
770 if (height <= 10)
772 vspacing = VSPACING_SMALL;
775 #if 0
776 renderimageframe(rp, DOWNIMAGE, state, pens,
777 left, top, width, height);
778 #endif
780 left++;
781 top++;
782 right--;
783 bottom--;
784 width -= 2;
785 height -= 2;
787 #if 0
788 SetAPen(rp, getbgpen(state, pens));
789 RectFill(rp, left, top, right, bottom);
790 #endif
792 left += hspacing;
793 top += vspacing;
794 width -= hspacing * 2;
795 height -= vspacing * 2;
797 right = left + width - 1;
798 bottom = top + height - 1;
800 cx = (width + 1) / 2;
802 SetAPen(rp, pens[SHADOWPEN]);
804 for(j = 0; j < 2; j++)
806 for(i = 0; i < cx; i++)
808 RectFill(rp, 1 - j + left + i,
809 1 - j + top + i * height / cx / 2,
810 1 - j + left + i,
811 1 - j + bottom - (cx - i - 1) * height / cx);
812 RectFill(rp, 1 - j + right - i,
813 1 - j + top + i * height / cx / 2,
814 1 - j + right - i,
815 1 - j + bottom - (cx - i - 1) * height / cx);
818 SetAPen(rp, pens[state == IDS_SELECTED ? BACKGROUNDPEN : SHINEPEN]);
820 break;
824 default:
825 return DoSuperMethodA(cl, obj, (Msg)msg);
828 return TRUE;
831 /**************************************************************************************************/
833 static void findtitlearea(struct Window *win, LONG *left, LONG *right)
835 struct Gadget *g;
837 *left = 0;
838 *right = win->Width - 1;
840 for (g = win->FirstGadget; g; g = g->NextGadget)
842 if (g->Activation & GACT_TOPBORDER &&
843 (g->GadgetType & GTYP_SYSTYPEMASK) != GTYP_WDRAGGING)
845 if (!(g->Flags & GFLG_RELRIGHT))
847 if (g->LeftEdge + g->Width > *left)
848 *left = g->LeftEdge + g->Width;
850 else
852 if (g->LeftEdge + win->Width - 1 - 1 < *right)
853 *right = g->LeftEdge + win->Width - 1 - 1;
860 /**************************************************************************************************/
862 IPTR windecor_draw_winborder(Class *cl, Object *obj, struct wdpDrawWinBorder *msg)
864 //struct windecor_data *data = INST_DATA(cl, obj);
865 struct RastPort *rp = msg->wdp_RPort;
866 struct Window *window = msg->wdp_Window;
867 //LONG left, right;
869 SetDrMd(rp, JAM1);
870 SetRPAttrs(rp, RPTAG_FgColor, 0xFFFFFF, RPTAG_BgColor, 0xFFFFFF, TAG_DONE);
872 if (window->BorderTop > 0)
874 /* Outer shine edge on top side */
876 CheckRectFill(rp, 0, 0, window->Width - 1, 0);
879 if (!(msg->wdp_Flags & WDF_DWB_TOP_ONLY))
881 if (window->BorderLeft > 0)
883 /* Outer shine edge on left side */
885 CheckRectFill(rp, 0, 0, 0, window->Height - 1);
888 if (window->BorderRight > 1)
890 /* Inner shine edge on right side */
892 CheckRectFill(rp,
893 window->Width - window->BorderRight, window->BorderTop,
894 window->Width - window->BorderRight, window->Height - window->BorderBottom);
897 if (window->BorderBottom > 1)
899 /* Inner shine edge on bottom side */
901 CheckRectFill(rp,
902 window->BorderLeft, window->Height - window->BorderBottom,
903 window->Width - window->BorderRight, window->Height - window->BorderBottom);
907 SetRPAttrs(rp, RPTAG_FgColor, 0x0, RPTAG_BgColor, 0x0, TAG_DONE);
909 if (!(msg->wdp_Flags & WDF_DWB_TOP_ONLY))
911 if (window->BorderRight > 0)
913 /* Outer shadow edge on right side */
915 CheckRectFill(rp, window->Width - 1, 1,
916 window->Width - 1, window->Height - 1);
919 if (window->BorderBottom > 0)
921 /* Outer shadow edge on bottom side */
923 CheckRectFill(rp, 1, window->Height - 1,
924 window->Width - 1, window->Height - 1);
927 if (window->BorderLeft > 1)
929 /* Inner shadow edge on left side */
931 CheckRectFill(rp, window->BorderLeft - 1, window->BorderTop - 1,
932 window->BorderLeft - 1, window->Height - window->BorderBottom);
937 if (window->BorderTop > 1)
939 /* Inner shadow edge on top side */
941 CheckRectFill(rp, window->BorderLeft - 1, window->BorderTop - 1,
942 window->Width - window->BorderRight, window->BorderTop - 1);
945 if ((window->Flags & WFLG_WINDOWACTIVE))
947 SetRPAttrs(rp, RPTAG_FgColor, ACTIVE_1, RPTAG_BgColor, ACTIVE_2, TAG_DONE);
949 else
951 SetRPAttrs(rp, RPTAG_FgColor, INACTIVE_1, RPTAG_BgColor, INACTIVE_2, TAG_DONE);
954 if (window->BorderTop > 2)
956 /* Fill on top side */
958 CheckRectFill(rp, 1, 1, window->Width - 2, window->BorderTop - 2);
961 if (!(msg->wdp_Flags & WDF_DWB_TOP_ONLY))
963 if ((window->Flags & WFLG_WINDOWACTIVE))
965 SetRPAttrs(rp, RPTAG_FgColor, ACTIVE_2, RPTAG_BgColor, ACTIVE_1, TAG_DONE);
967 else
969 SetRPAttrs(rp, RPTAG_FgColor, INACTIVE_2, RPTAG_BgColor, INACTIVE_1, TAG_DONE);
972 if (window->BorderLeft > 2)
974 /* Fill on left side */
976 CheckRectFill(rp, 1, window->BorderTop, window->BorderLeft - 2, window->Height - 2);
980 if (window->BorderRight > 2)
982 /* Fill on right side */
984 CheckRectFill(rp, window->Width - window->BorderRight + 1, window->BorderTop,
985 window->Width - 2, window->Height - 2);
988 if ((window->Flags & WFLG_WINDOWACTIVE))
990 SetRPAttrs(rp, RPTAG_FgColor, ACTIVE_1, RPTAG_BgColor, ACTIVE_2, TAG_DONE);
992 else
994 SetRPAttrs(rp, RPTAG_FgColor, INACTIVE_1, RPTAG_BgColor, INACTIVE_2, TAG_DONE);
997 if (window->BorderBottom > 2)
999 /* Fill on bottom side */
1001 CheckRectFill(rp, 1, window->Height - window->BorderBottom + 1,
1002 window->Width - 2, window->Height - 2);
1006 #if 0
1007 findtitlearea(window, &left, &right);
1009 if (left != 0)
1011 /* Left edge of title area */
1013 SetAPen(rp, pens[SHINEPEN]);
1014 Move(rp, left, 1);
1015 Draw(rp, left, window->BorderTop - 2);
1018 if (right != window->Width - 1)
1020 /* Right edges of title area */
1022 SetAPen(rp, pens[SHADOWPEN]);
1023 Move(rp, right, 1);
1024 Draw(rp, right, window->BorderTop - 2);
1026 #endif
1028 return TRUE;
1031 /**************************************************************************************************/
1033 IPTR windecor_draw_wintitle(Class *cl, Object *obj, struct wdpDrawWinTitle *msg)
1035 struct windecor_data *data = INST_DATA(cl, obj);
1036 struct RastPort *rp = msg->wdp_RPort;
1037 struct Window *window = msg->wdp_Window;
1038 UWORD *pens = data->dri->dri_Pens;
1039 LONG right, left;
1041 findtitlearea(window, &left, &right);
1043 SetDrMd(rp, JAM1);
1044 if (window->Flags & WFLG_WINDOWACTIVE)
1046 SetRPAttrs(rp, RPTAG_FgColor, ACTIVE_1, RPTAG_BgColor, ACTIVE_2, TAG_DONE);
1048 else
1050 SetRPAttrs(rp, RPTAG_FgColor, INACTIVE_1, RPTAG_BgColor, INACTIVE_2, TAG_DONE);
1053 SetAPen(rp, pens[(window->Flags & WFLG_WINDOWACTIVE) ? FILLPEN : BACKGROUNDPEN]);
1054 CheckRectFill(rp, left + 1, 1, right - 1, window->BorderTop - 2);
1056 if (right - left > 6)
1058 ULONG textlen, titlelen, textpixellen;
1059 struct TextExtent te;
1061 SetFont(rp, data->dri->dri_Font);
1063 titlelen = strlen(window->Title);
1064 textlen = TextFit(rp
1065 , window->Title
1066 , titlelen
1067 , &te
1068 , NULL
1070 , right - left - 6
1071 , window->BorderTop - 2);
1072 if (textlen)
1074 textpixellen = te.te_Extent.MaxX - te.te_Extent.MinX + 1;
1076 switch(msg->wdp_TitleAlign)
1078 case WD_DWTA_CENTER:
1079 if (textlen == titlelen)
1081 left = (left + right + 1 - textpixellen) / 2;
1083 else
1085 left = left + 3;
1087 break;
1089 case WD_DWTA_RIGHT:
1090 if (textlen == titlelen)
1092 left = right - textpixellen;
1094 else
1096 left = left + 3;
1098 break;
1100 default:
1101 case WD_DWTA_LEFT:
1102 left = left + 3;
1103 break;
1107 SetAPen(rp, pens[(window->Flags & WFLG_WINDOWACTIVE) ? FILLTEXTPEN : TEXTPEN]);
1109 SetAPen(rp, pens[SHADOWPEN]);
1110 Move(rp, left + 1, data->dri->dri_Font->tf_Baseline + 2 + 1);
1111 Text(rp, window->Title, textlen);
1113 SetAPen(rp, pens[SHINEPEN]);
1114 Move(rp, left, data->dri->dri_Font->tf_Baseline + 2);
1115 Text(rp, window->Title, textlen);
1120 return TRUE;
1123 /**************************************************************************************************/
1125 IPTR windecor_layout_bordergadgets(Class *cl, Object *obj, struct wdpLayoutBorderGadgets *msg)
1127 //struct windecor_data *data = INST_DATA(cl, obj);
1128 struct Window *window = msg->wdp_Window;
1129 struct Gadget *gadget = msg->wdp_Gadgets;
1130 BOOL hasdepth;
1131 BOOL haszoom;
1132 BOOL hasclose;
1134 DoSuperMethodA(cl, obj, (Msg)msg);
1136 hasclose = (window->Flags & WFLG_CLOSEGADGET) ? TRUE : FALSE;
1137 hasdepth = (window->Flags & WFLG_DEPTHGADGET) ? TRUE : FALSE;
1138 haszoom = ((window->Flags & WFLG_HASZOOM) ||
1139 ((window->Flags & WFLG_SIZEGADGET) && hasdepth)) ? TRUE : FALSE;
1141 while(gadget)
1143 switch(gadget->GadgetType & GTYP_SYSTYPEMASK)
1145 case GTYP_CLOSE:
1146 gadget->LeftEdge = -gadget->Height + 1;
1147 gadget->Width = gadget->Height;
1148 gadget->Flags &= ~GFLG_RELWIDTH;
1149 gadget->Flags |= GFLG_RELRIGHT;
1150 break;
1152 case GTYP_WDEPTH:
1153 gadget->LeftEdge = -gadget->Height * (hasclose ? 2 : 1) - hasclose * 3 + 1;
1154 gadget->Width = gadget->Height;
1155 gadget->Flags &= ~GFLG_RELWIDTH;
1156 gadget->Flags |= GFLG_RELRIGHT;
1157 break;
1159 case GTYP_WZOOM:
1160 gadget->LeftEdge = -gadget->Height * (hasclose ? 3 : 1) - hasclose * 3 + 1;
1161 gadget->Width = gadget->Height;
1162 gadget->Flags &= ~GFLG_RELWIDTH;
1163 gadget->Flags |= GFLG_RELRIGHT;
1164 break;
1168 if (msg->wdp_Flags & WDF_LBG_MULTIPLE)
1170 gadget = gadget->NextGadget;
1172 else
1174 gadget = NULL;
1178 return TRUE;
1181 /**************************************************************************************************/
1183 IPTR windecor_draw_borderpropback(Class *cl, Object *obj, struct wdpDrawBorderPropBack *msg)
1185 struct windecor_data *data = INST_DATA(cl, obj);
1186 struct Window *window = msg->wdp_Window;
1187 struct RastPort *rp, *winrp = msg->wdp_RPort;
1188 struct Gadget *gadget = msg->wdp_Gadget;
1189 struct Rectangle *r = msg->wdp_RenderRect;
1190 struct PropInfo *pi = ((struct PropInfo *)gadget->SpecialInfo);
1191 UWORD *pens = data->dri->dri_Pens;
1193 if (!(pi->Flags & PROPNEWLOOK))
1195 return DoSuperMethodA(cl, obj, (Msg)msg);
1198 if ((rp = CloneRastPort(winrp)))
1200 struct TagItem rptags[] =
1202 {RPTAG_ClipRectangle , (IPTR)msg->wdp_RenderRect },
1203 {RPTAG_ClipRectangleFlags , 0 },
1204 {RPTAG_DrMd , JAM2 },
1205 {TAG_DONE }
1208 SetRPAttrsA(rp, rptags);
1210 r = msg->wdp_PropRect;
1212 SetAPen(rp, pens[SHADOWPEN]);
1213 RectFill(rp, r->MinX, r->MinY, r->MaxX, r->MinY);
1214 RectFill(rp, r->MinX, r->MinY + 1, r->MinX, r->MaxY);
1215 SetAPen(rp, pens[SHINEPEN]);
1216 RectFill(rp, r->MaxX, r->MinY + 1, r->MaxX, r->MaxY);
1217 RectFill(rp, r->MinX + 1, r->MaxY, r->MaxX - 1, r->MaxY);
1219 SetAPen(rp, pens[(window->Flags & WFLG_WINDOWACTIVE) ? SHADOWPEN : BACKGROUNDPEN]);
1220 RectFill(rp, r->MinX + 1, r->MinY + 1, r->MaxX - 1, r->MaxY - 1);
1222 FreeRastPort(rp);
1226 return TRUE;
1229 /**************************************************************************************************/
1231 IPTR windecor_draw_borderpropknob(Class *cl, Object *obj, struct wdpDrawBorderPropKnob *msg)
1233 struct windecor_data *data = INST_DATA(cl, obj);
1234 struct Window *window = msg->wdp_Window;
1235 struct RastPort *rp = msg->wdp_RPort;
1236 struct Gadget *gadget = msg->wdp_Gadget;
1237 struct Rectangle *r = msg->wdp_RenderRect;
1238 struct PropInfo *pi = ((struct PropInfo *)gadget->SpecialInfo);
1239 UWORD *pens = data->dri->dri_Pens;
1240 BOOL hit = (msg->wdp_Flags & WDF_DBPK_HIT) ? TRUE : FALSE;
1242 if (!(pi->Flags & PROPBORDERLESS))
1244 return DoSuperMethodA(cl, obj, (Msg)msg);
1247 SetDrMd(rp, JAM2);
1249 SetAPen(rp, pens[hit ? SHADOWPEN : SHINEPEN]);
1251 /* Top edge */
1252 RectFill(rp, r->MinX, r->MinY, r->MaxX - 1, r->MinY);
1254 /* Left edge */
1255 RectFill(rp, r->MinX, r->MinY + 1, r->MinX, r->MaxY - 1);
1257 SetAPen(rp, pens[hit ? SHINEPEN : SHADOWPEN]);
1259 /* Right edge */
1260 RectFill(rp, r->MaxX, r->MinY, r->MaxX, r->MaxY);
1262 /* Bottom edge */
1263 RectFill(rp, r->MinX, r->MaxY, r->MaxX - 1, r->MaxY);
1265 r->MinX++;
1266 r->MinY++;
1267 r->MaxX--;
1268 r->MaxY--;
1270 if ((window->Flags & WFLG_WINDOWACTIVE))
1272 ULONG col = hit ? 0xb9b6ff : 0xadaaee;
1274 SetRPAttrs(rp, RPTAG_FgColor, col, TAG_DONE);
1276 else
1278 SetAPen(rp, pens[BACKGROUNDPEN]);
1281 /* interior */
1282 RectFill(rp, r->MinX, r->MinY, r->MaxX, r->MaxY);
1284 return TRUE;
1287 /**************************************************************************************************/
1289 IPTR windecor_dispatcher(struct IClass *cl, Object *obj, Msg msg)
1291 IPTR retval;
1293 switch(msg->MethodID)
1295 case OM_NEW:
1296 retval = windecor_new(cl, obj, (struct opSet *)msg);
1297 break;
1299 case OM_GET:
1300 retval = windecor_get(cl, obj, (struct opGet *)msg);
1301 break;
1303 case WDM_DRAW_SYSIMAGE:
1304 retval = windecor_draw_sysimage(cl, obj, (struct wdpDrawSysImage *)msg);
1305 break;
1307 case WDM_DRAW_WINBORDER:
1308 retval = windecor_draw_winborder(cl, obj, (struct wdpDrawWinBorder *)msg);
1309 break;
1311 case WDM_DRAW_WINTITLE:
1312 retval = windecor_draw_wintitle(cl, obj, (struct wdpDrawWinTitle *)msg);
1313 break;
1315 case WDM_LAYOUT_BORDERGADGETS:
1316 retval = windecor_layout_bordergadgets(cl, obj, (struct wdpLayoutBorderGadgets *)msg);
1317 break;
1319 case WDM_DRAW_BORDERPROPBACK:
1320 retval = windecor_draw_borderpropback(cl, obj, (struct wdpDrawBorderPropBack *)msg);
1321 break;
1323 case WDM_DRAW_BORDERPROPKNOB:
1324 retval = windecor_draw_borderpropknob(cl, obj, (struct wdpDrawBorderPropKnob *)msg);
1325 break;
1327 default:
1328 retval = DoSuperMethodA(cl, obj, msg);
1329 break;
1333 return retval;
1336 /**************************************************************************************************/
1338 struct scrdecor_data
1340 struct DrawInfo *dri;
1341 struct Screen *scr;
1344 /**************************************************************************************************/
1346 static IPTR scrdecor_new(Class *cl, Object *obj, struct opSet *msg)
1348 struct scrdecor_data *data;
1350 obj = (Object *)DoSuperMethodA(cl, obj, (Msg)msg);
1351 if (obj)
1353 data = INST_DATA(cl, obj);
1355 data->dri = (struct DrawInfo *)GetTagData(SDA_DrawInfo, 0, msg->ops_AttrList);
1356 data->scr = (struct Screen *)GetTagData(SDA_Screen, 0, msg->ops_AttrList);
1358 if (!data->dri || !data->scr)
1360 STACKULONG method = OM_DISPOSE;
1362 CoerceMethodA(cl, obj, (Msg)&method);
1364 return 0;
1369 return (IPTR)obj;
1372 /**************************************************************************************************/
1374 static IPTR scrdecor_get(Class *cl, Object *obj, struct opGet *msg)
1376 //struct scrdecor_data *data = INST_DATA(cl, obj);
1378 switch(msg->opg_AttrID)
1380 case SDA_TrueColorOnly:
1381 *msg->opg_Storage = TRUE;
1382 break;
1384 default:
1385 return DoSuperMethodA(cl, obj, (Msg)msg);
1388 return 1;
1391 /**************************************************************************************************/
1393 static void findscrtitlearea(struct Screen *scr, LONG *left, LONG *right)
1395 struct Gadget *g;
1397 *left = 0;
1398 *right = scr->Width - 1;
1400 for (g = scr->FirstGadget; g; g = g->NextGadget)
1402 if (!(g->Flags & GFLG_RELRIGHT))
1404 if (g->LeftEdge + g->Width > *left)
1405 *left = g->LeftEdge + g->Width;
1407 else
1409 if (g->LeftEdge + scr->Width - 1 - 1 < *right)
1410 *right = g->LeftEdge + scr->Width - 1 - 1;
1416 /**************************************************************************************************/
1418 ULONG coltab[] =
1420 0xEEEEEE,
1421 0xFFFFFF,
1422 0xFFFFFF,
1423 0xFFFFFF,
1424 0xEEEEEE,
1425 0xFFFFFF,
1426 0xFFFFFF,
1427 0xFFFFFF,
1428 0xEEEEEE,
1429 0xFFFFFF,
1430 0xFFFFFF,
1431 0xFFFFFF,
1432 0xDDDDDD,
1433 0x777777
1436 /**************************************************************************************************/
1438 IPTR scrdecor_draw_screenbar(Class *cl, Object *obj, struct sdpDrawScreenBar *msg)
1440 struct scrdecor_data *data = INST_DATA(cl, obj);
1441 struct RastPort *rp = msg->sdp_RPort;
1442 UWORD *pens = data->dri->dri_Pens;
1443 LONG left, right, y;
1445 SetDrMd(rp, JAM1);
1446 for(y = 0; y <= data->scr->BarHeight; y++)
1448 ULONG col;
1450 col = coltab[y * (sizeof(coltab) / sizeof(coltab[0])) / data->scr->BarHeight];
1452 FillPixelArray(rp, 0, y, data->scr->Width, 1, col);
1455 findscrtitlearea(data->scr, &left, &right);
1457 SetAPen(rp, pens[SHADOWPEN]);
1458 RectFill(rp, right, 1, right, data->scr->BarHeight - 1);
1460 FillPixelArray(rp, data->scr->BarHBorder + 4, 4,
1461 data->scr->BarHeight - 8, data->scr->BarHeight - 8,
1463 FillPixelArray(rp, data->scr->BarHBorder + 4, 4,
1464 data->scr->BarHeight - 8, 1,
1465 0x777777);
1466 FillPixelArray(rp, data->scr->BarHBorder + 4, 4,
1467 1, data->scr->BarHeight - 8,
1468 0x777777);
1469 FillPixelArray(rp, data->scr->BarHBorder + 5, 5,
1470 data->scr->BarHeight - 9, data->scr->BarHeight - 9,
1471 0x0b750e);
1473 return TRUE;
1476 /**************************************************************************************************/
1478 IPTR scrdecor_draw_screentitle(Class *cl, Object *obj, struct sdpDrawScreenTitle *msg)
1480 struct scrdecor_data *data = INST_DATA(cl, obj);
1481 struct RastPort *rp = msg->sdp_RPort;
1482 LONG right, left, y;
1483 WORD oldspacing;
1485 findscrtitlearea(data->scr, &left, &right);
1487 SetDrMd(rp, JAM1);
1488 for(y = 0; y <= data->scr->BarHeight; y++)
1490 ULONG col;
1492 col = coltab[y * (sizeof(coltab) / sizeof(coltab[0])) / data->scr->BarHeight];
1494 FillPixelArray(rp, data->scr->BarHBorder + data->scr->BarHeight, y,
1495 (right - 1) - (data->scr->BarHBorder + data->scr->BarHeight) + 1, 1, col);
1498 oldspacing = rp->TxSpacing;
1499 rp->TxSpacing = 1;
1501 Move(rp, data->scr->BarHBorder + data->scr->BarHeight + data->scr->BarHBorder, data->scr->BarVBorder + rp->TxBaseline);
1502 Text(rp, data->scr->Title, strlen(data->scr->Title));
1503 Move(rp, data->scr->BarHBorder + data->scr->BarHeight + data->scr->BarHBorder + 1, data->scr->BarVBorder + rp->TxBaseline);
1504 Text(rp, data->scr->Title, strlen(data->scr->Title));
1506 rp->TxSpacing = oldspacing;
1508 return TRUE;
1512 /**************************************************************************************************/
1514 IPTR scrdecor_dispatcher(struct IClass *cl, Object *obj, Msg msg)
1516 IPTR retval;
1518 switch(msg->MethodID)
1520 case OM_NEW:
1521 retval = scrdecor_new(cl, obj, (struct opSet *)msg);
1522 break;
1524 case OM_GET:
1525 retval = scrdecor_get(cl, obj, (struct opGet *)msg);
1526 break;
1528 case SDM_DRAW_SCREENBAR:
1529 retval = scrdecor_draw_screenbar(cl, obj, (struct sdpDrawScreenBar *)msg);
1530 break;
1532 case SDM_DRAW_SCREENTITLE:
1533 retval = scrdecor_draw_screentitle(cl, obj, (struct sdpDrawScreenTitle *)msg);
1534 break;
1536 default:
1537 retval = DoSuperMethodA(cl, obj, msg);
1538 break;
1542 return retval;
1545 /**************************************************************************************************/
1547 int main(void)
1549 scr = LockPubScreen(NULL);
1550 if (scr)
1552 dri = GetScreenDrawInfo(scr);
1553 if (dri)
1555 cl = MakeClass("testwindecor", WINDECORCLASS, NULL, sizeof(struct windecor_data), 0);
1556 if (cl)
1558 cl->cl_Dispatcher.h_Entry = HookEntry;
1559 cl->cl_Dispatcher.h_SubEntry = (HOOKFUNC)windecor_dispatcher;
1561 AddClass(cl);
1563 scrcl = MakeClass("testscrdecor", SCRDECORCLASS, NULL, sizeof(struct scrdecor_data), 0);
1564 if (scrcl)
1566 scrcl->cl_Dispatcher.h_Entry = HookEntry;
1567 scrcl->cl_Dispatcher.h_SubEntry = (HOOKFUNC)scrdecor_dispatcher;
1569 AddClass(scrcl);
1571 olddecorobj = ChangeDecorationA(DECORATION_WINDOW, "testwindecor", dri, NULL);
1572 if (!olddecorobj) puts("Coult not change window decoration!\n");
1574 oldscrdecorobj = ChangeDecorationA(DECORATION_SCREEN, "testscrdecor", dri, NULL);
1575 if (!oldscrdecorobj) puts("Coult not change screen decoration!\n");
1577 if (olddecorobj || oldscrdecorobj)
1579 puts("Press CTRL-C to quit\n");
1580 Wait(SIGBREAKF_CTRL_C);
1583 if (olddecorobj)
1585 thisdecorobj = ChangeDecorationA(DECORATION_WINDOW, OCLASS(olddecorobj)->cl_ID, dri, NULL);
1587 DisposeObject(olddecorobj);
1588 DisposeObject(thisdecorobj);
1591 if (oldscrdecorobj)
1593 thisscrdecorobj = ChangeDecorationA(DECORATION_SCREEN, OCLASS(oldscrdecorobj)->cl_ID, dri, NULL);
1595 DisposeObject(oldscrdecorobj);
1596 DisposeObject(thisscrdecorobj);
1599 FreeClass(scrcl);
1601 else puts("Could not create testscrdecor class!\n");
1603 FreeClass(cl);
1605 else puts("Coult not create testwindecor class!\n");
1607 FreeScreenDrawInfo(scr, dri);
1609 else puts("Could not get DrawInfo!\n");
1611 UnlockPubScreen(NULL, scr);
1613 else puts("Could not lock pub screen!");
1615 return 0;