New bitmap method SetRGBConversionFunction which can be used to
[tangerine.git] / rom / intuition / windecorclass.c
blobd0babe84ded1cae4705aec80e7ec20ffd0d69719
1 /*
2 Copyright © 1995-2005, The AROS Development Team. All rights reserved.
3 Copyright © 2001-2003, The MorphOS Development Team. All Rights Reserved.
4 $Id: imageclass.c 20651 2004-01-17 20:57:12Z chodorowski $
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 WORD right = left + width - 1;
71 WORD bottom = top + height - 1;
72 BOOL leftedgegodown = FALSE;
73 BOOL topedgegoright = FALSE;
75 switch(which)
77 #if 0
78 case CLOSEIMAGE:
79 /* draw separator line at the right side */
80 SetAPen(rp, pens[SHINEPEN]);
81 RectFill(rp, right, top, right, bottom - 1);
82 SetAPen(rp, pens[SHADOWPEN]);
83 WritePixel(rp, right, bottom);
85 right--;
86 break;
88 case ZOOMIMAGE:
89 case DEPTHIMAGE:
90 case SDEPTHIMAGE:
91 /* draw separator line at the left side */
92 SetAPen(rp, pens[SHINEPEN]);
93 WritePixel(rp, left, top);
94 SetAPen(rp, pens[SHADOWPEN]);
95 RectFill(rp, left, top + 1, left, bottom);
97 left++;
98 break;
99 #endif
101 case UPIMAGE:
102 case DOWNIMAGE:
103 leftedgegodown = TRUE;
104 break;
106 case LEFTIMAGE:
107 case RIGHTIMAGE:
108 topedgegoright = TRUE;
109 break;
112 if (left == 0) leftedgegodown = TRUE;
113 if (top == 0) topedgegoright = TRUE;
115 SetAPen(rp, pens[((state == IDS_SELECTED) || (state == IDS_INACTIVESELECTED)) ? SHADOWPEN : SHINEPEN]);
117 /* left edge */
118 RectFill(rp, left,
119 top,
120 left,
121 bottom - (leftedgegodown ? 0 : 1));
123 /* top edge */
124 RectFill(rp, left + 1,
125 top,
126 right - (topedgegoright ? 0 : 1),
127 top);
129 SetAPen(rp, pens[((state == IDS_SELECTED) || (state == IDS_INACTIVESELECTED)) ? SHINEPEN : SHADOWPEN]);
131 /* right edge */
132 RectFill(rp, right,
133 top + (topedgegoright ? 1 : 0),
134 right,
135 bottom);
137 /* bottom edge */
138 RectFill(rp, left + (leftedgegodown ? 1 : 0),
139 bottom,
140 right - 1,
141 bottom);
144 /**************************************************************************************************/
146 static UWORD getbgpen(ULONG state, UWORD *pens)
148 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 #undef IntuitionBase
169 #define IntuitionBase ((struct IntuitionBase *)(cl->cl_UserData))
171 /**************************************************************************************************/
173 IPTR WinDecorClass__OM_NEW(Class *cl, Object *obj, struct opSet *msg)
175 struct windecor_data *data;
177 obj = (Object *)DoSuperMethodA(cl, obj, (Msg)msg);
178 if (obj)
180 data = INST_DATA(cl, obj);
182 data->dri = (struct IntDrawInfo *)GetTagData(WDA_DrawInfo, 0, msg->ops_AttrList);
183 data->scr = (struct Screen *)GetTagData(WDA_Screen, 0, msg->ops_AttrList);
185 if (!data->dri || !data->scr)
187 STACKULONG method = OM_DISPOSE;
189 CoerceMethodA(cl, obj, (Msg)&method);
191 return 0;
196 return (IPTR)obj;
199 /**************************************************************************************************/
201 IPTR WinDecorClass__OM_GET(Class *cl, Object *obj, struct opGet *msg)
203 struct windecor_data *data = INST_DATA(cl, obj);
205 switch(msg->opg_AttrID)
207 case WDA_DrawInfo:
208 *msg->opg_Storage = (IPTR)data->dri;
209 break;
211 case WDA_Screen:
212 *msg->opg_Storage = (IPTR)data->scr;
213 break;
215 case WDA_TrueColorOnly:
216 *msg->opg_Storage = FALSE;
217 break;
219 default:
220 return DoSuperMethodA(cl, obj, (Msg)msg);
223 return 1;
227 /**************************************************************************************************/
229 IPTR WinDecorClass__WDM_GETDEFSIZE_SYSIMAGE(Class *cl, Object *obj, struct wdpGetDefSizeSysImage *msg)
231 ULONG def_low_width = DEFSIZE_WIDTH, def_low_height = DEFSIZE_HEIGHT;
232 ULONG def_med_width = DEFSIZE_WIDTH, def_med_height = DEFSIZE_HEIGHT;
233 ULONG def_high_width = DEFSIZE_WIDTH, def_high_height = DEFSIZE_HEIGHT;
235 #define REFHEIGHT (msg->wdp_ReferenceFont->tf_YSize)
236 #define REFWIDTH REFHEIGHT
238 switch(msg->wdp_Which)
240 case LEFTIMAGE:
241 case RIGHTIMAGE:
242 #if USE_AROS_DEFSIZE
243 def_low_width = def_med_width = def_high_width = DEFSIZE_WIDTH;
244 def_low_height = def_med_height = def_high_height = DEFSIZE_HEIGHT;
245 #else
246 def_low_width = 16;
247 def_med_width = 16;
248 def_high_width = 23;
249 def_low_height = 11;
250 def_med_height = 10;
251 def_high_height = 22;
252 #endif
253 break;
255 case UPIMAGE:
256 case DOWNIMAGE:
257 #if USE_AROS_DEFSIZE
258 def_low_width = def_med_width = def_high_width = DEFSIZE_WIDTH;
259 def_low_height = def_med_height = def_high_height = DEFSIZE_HEIGHT;
260 #else
261 def_low_width = 13;
262 def_med_width = 18;
263 def_high_width = 23;
264 def_low_height = 11;
265 def_med_height = 11;
266 def_high_height = 22;
267 #endif
268 break;
270 case DEPTHIMAGE:
271 case ZOOMIMAGE:
272 case ICONIFYIMAGE:
273 case LOCKIMAGE:
274 case MUIIMAGE:
275 case POPUPIMAGE:
276 case SNAPSHOTIMAGE:
277 case JUMPIMAGE:
278 #if USE_AROS_DEFSIZE
279 def_low_width = def_med_width = def_high_width = DEFSIZE_WIDTH;
280 def_low_height = def_med_height = def_high_height = DEFSIZE_HEIGHT;
281 #else
282 def_low_width = 18;
283 def_med_width = 24;
284 def_high_width = 24;
285 #endif
286 break;
288 case SDEPTHIMAGE:
289 #if USE_AROS_DEFSIZE
290 def_low_width = def_med_width = def_high_width = DEFSIZE_WIDTH;
291 def_low_height = def_med_height = def_high_height = DEFSIZE_HEIGHT;
292 #else
293 def_low_width = 17;
294 def_med_width = 23;
295 def_high_width = 23;
296 #endif
297 break;
299 case CLOSEIMAGE:
300 #if USE_AROS_DEFSIZE
301 def_low_width = def_med_width = def_high_width = DEFSIZE_WIDTH;
302 def_low_height = def_med_height = def_high_height = DEFSIZE_HEIGHT;
303 #else
304 def_low_width = 15;
305 def_med_width = 20;
306 def_high_width = 20;
307 #endif
308 break;
310 case SIZEIMAGE:
311 #if USE_AROS_DEFSIZE
312 def_low_width = def_med_width = def_high_width = DEFSIZE_WIDTH;
313 def_low_height = def_med_height = def_high_height = DEFSIZE_HEIGHT;
314 #else
315 def_low_width = 13;
316 def_med_width = 18;
317 def_high_width = 18;
318 def_low_height = 11;
319 def_med_height = 10;
320 def_high_height = 10;
321 #endif
322 break;
324 case MENUCHECK:
325 def_low_width =
326 def_med_width =
327 def_high_width = REFWIDTH / 2 + 4; // reffont->tf_XSize * 3 / 2;
328 def_low_height =
329 def_med_height =
330 def_high_height= REFHEIGHT;
331 break;
333 case MXIMAGE:
334 def_low_width =
335 def_med_width =
336 def_high_width = (REFWIDTH + 1) * 2; // reffont->tf_XSize * 3 - 1;
337 def_low_height =
338 def_med_height =
339 def_high_height= REFHEIGHT + 1;
340 break;
342 case CHECKIMAGE:
343 def_low_width = (REFWIDTH + 3) * 2;//reffont->tf_XSize * 2;
344 def_low_height = REFHEIGHT + 3;
345 break;
347 default:
348 return FALSE;
351 switch(msg->wdp_SysiSize)
353 case SYSISIZE_LOWRES:
354 *msg->wdp_Width = def_low_width;
355 *msg->wdp_Height = def_low_height;
356 break;
358 case SYSISIZE_MEDRES:
359 *msg->wdp_Width = def_med_width;
360 *msg->wdp_Height = def_med_height;
361 break;
363 case SYSISIZE_HIRES:
364 default:
365 *msg->wdp_Width = def_high_width;
366 *msg->wdp_Height = def_high_height;
367 break;
370 return TRUE;
373 /**************************************************************************************************/
375 IPTR WinDecorClass__WDM_DRAW_SYSIMAGE(Class *cl, Object *obj, struct wdpDrawSysImage *msg)
377 struct windecor_data *data = INST_DATA(cl, obj);
378 struct RastPort *rp = msg->wdp_RPort;
379 UWORD *pens = DRI(data->dri)->dri_Pens;
380 LONG state = msg->wdp_State;
381 LONG left = msg->wdp_X;
382 LONG top = msg->wdp_Y;
383 LONG width = msg->wdp_Width;
384 LONG height = msg->wdp_Height;
385 LONG right = left + width - 1;
386 LONG bottom = top + height - 1;
387 LONG h_spacing, v_spacing;
389 SetDrMd(rp, JAM1);
391 switch(msg->wdp_Which)
393 case CLOSEIMAGE:
395 renderimageframe(rp, CLOSEIMAGE, state, pens, left, top, width, height, IntuitionBase);
396 left++;
397 top++;
398 width -= 2;
399 height -= 2;
401 right = left + width - 1;
402 bottom = top + height - 1;
403 h_spacing = width * 4 / 10;
404 v_spacing = height * 3 / 10;
406 SetAPen(rp, getbgpen(state, pens));
407 RectFill(rp, left, top, right, bottom);
409 left += h_spacing;
410 right -= h_spacing;
411 top += v_spacing;
412 bottom -= v_spacing;
414 SetAPen(rp, pens[SHADOWPEN]);
415 RectFill(rp, left, top, right, bottom);
417 left++;
418 top++;
419 right--;
420 bottom--;
422 SetAPen(rp, pens[(state == IDS_NORMAL) ? SHINEPEN : BACKGROUNDPEN]);
423 RectFill(rp, left, top, right, bottom);
425 break;
428 case ZOOMIMAGE:
430 UWORD bg;
431 WORD h_spacing;
432 WORD v_spacing;
434 renderimageframe(rp, ZOOMIMAGE, state, pens,
435 left, top, width, height, IntuitionBase);
436 left++;
437 top++;
438 width -= 2;
439 height -= 2;
441 right = left + width - 1;
442 bottom = top + height - 1 ;
443 h_spacing = width / 6;
444 v_spacing = height / 6;
446 bg = getbgpen(state, pens);
448 /* Clear background into correct color */
449 SetAPen(rp, bg);
450 RectFill(rp, left, top, right, bottom);
452 left += h_spacing;
453 right -= h_spacing;
454 top += v_spacing;
455 bottom -= v_spacing;
457 SetAPen(rp, pens[SHADOWPEN]);
458 RectFill(rp, left, top, right, bottom);
460 SetAPen(rp, pens[(state == IDS_SELECTED) ? SHINEPEN :
461 (state == IDS_NORMAL) ? FILLPEN : BACKGROUNDPEN]);
462 RectFill(rp, left + 1, top + 1, right - 1, bottom - 1);
464 right = left + (right - left + 1) / 2;
465 bottom = top + (bottom - top + 1) / 2;
467 if (right - left < 4) right = left + 4;
469 SetAPen(rp, pens[SHADOWPEN]);
470 RectFill(rp, left, top, right, bottom);
472 left += 2;
473 right -= 2;
474 top += 1;
475 bottom -= 1;
477 SetAPen(rp, pens[(state == IDS_SELECTED) ? FILLPEN :
478 (state == IDS_NORMAL) ? SHINEPEN : BACKGROUNDPEN]);
479 RectFill(rp,left, top, right, bottom);
480 break;
483 case DEPTHIMAGE:
485 UWORD bg;
486 WORD h_spacing;
487 WORD v_spacing;
489 renderimageframe(rp, DEPTHIMAGE, state, pens,
490 left, top, width, height, IntuitionBase);
491 left++;
492 top++;
493 right--;
494 bottom--;
495 width -= 2;
496 height -= 2;
498 h_spacing = width / 6;
499 v_spacing = height / 6;
501 bg = getbgpen(state, pens);
503 /* Clear background into correct color */
504 SetAPen(rp, bg);
505 RectFill(rp, left, top, right, bottom);
507 /* Draw a image of two partly overlapped tiny windows,
510 left += h_spacing;
511 top += v_spacing;
513 width -= h_spacing * 2;
514 height -= v_spacing * 2;
516 right = left + width - 1;
517 bottom = top + height - 1;
519 /* Render top left window */
521 SetAPen(rp, pens[SHADOWPEN]);
522 drawrect(rp
523 , left
524 , top
525 , right - (width / 3 )
526 , bottom - (height / 3)
527 , IntuitionBase);
530 /* Fill top left window (inside of the frame above) */
532 if ((state != IDS_INACTIVENORMAL))
534 SetAPen(rp, pens[BACKGROUNDPEN]);
535 RectFill(rp, left + 1, top + 1,
536 right - (width / 3) - 1, bottom - (height / 3) - 1);
540 /* Render bottom right window */
541 SetAPen(rp, pens[SHADOWPEN]);
542 drawrect(rp, left + (width / 3), top + (height / 3),
543 right, bottom, IntuitionBase);
545 /* Fill bottom right window (inside of the frame above) */
546 SetAPen(rp, pens[(state == IDS_INACTIVENORMAL) ? BACKGROUNDPEN : SHINEPEN]);
547 RectFill(rp, left + (width / 3) + 1, top + (height / 3) + 1,
548 right - 1, bottom - 1);
550 if (state == IDS_SELECTED)
552 /* Re-Render top left window */
554 SetAPen(rp, pens[SHADOWPEN]);
555 drawrect(rp, left, top,
556 right - (width / 3 ), bottom - (height / 3), IntuitionBase);
558 break;
561 case SIZEIMAGE:
563 UWORD bg;
564 WORD h_spacing;
565 WORD v_spacing;
566 WORD x, y;
568 renderimageframe(rp, SIZEIMAGE, state, pens,
569 left, top, width, height, IntuitionBase);
570 left++;
571 top++;
572 right--;
573 bottom--;
574 width -= 2;
575 height -= 2;
577 h_spacing = width / 5;
578 v_spacing = height / 5;
580 bg = getbgpen(state, pens);
582 /* Clear background into correct color */
583 SetAPen(rp, bg);
584 RectFill(rp, left, top, right, bottom);
586 /* A triangle image */
588 left += h_spacing;
589 top += v_spacing;
591 right = left + width - 1 - (h_spacing * 2);
592 bottom = top + height - 1 - (v_spacing * 2);
594 width = right - left + 1;
595 height = bottom - top + 1;
597 if (state != IDS_INACTIVENORMAL)
599 SetAPen(rp, pens[SHINEPEN]);
601 for(y = top; y <= bottom; y++)
603 x = left + (bottom - y) * width / height;
604 RectFill(rp, x, y, right, y);
608 SetAPen(rp, pens[SHADOWPEN]);
609 /* Draw triangle border */
610 Move(rp, left, bottom);
611 Draw(rp, right, top);
612 Draw(rp, right, bottom);
613 Draw(rp, left, bottom);
615 break;
618 case LEFTIMAGE:
620 UWORD hspacing,vspacing;
621 WORD cy, i;
623 hspacing = HSPACING;
624 vspacing = VSPACING;
626 if (width <= 12)
628 hspacing = HSPACING_MIDDLE;
631 if (width <= 10)
633 hspacing = HSPACING_SMALL;
636 if (height <= 12)
638 vspacing = VSPACING_MIDDLE;
641 if (height <= 10)
643 vspacing = VSPACING_SMALL;
646 renderimageframe(rp, LEFTIMAGE, state, pens,
647 left, top, width, height, IntuitionBase);
648 left++;
649 top++;
650 right--;
651 bottom--;
652 width -= 2;
653 height -= 2;
655 SetAPen(rp, getbgpen(state, pens));
656 RectFill(rp, left, top, right, bottom);
658 left += hspacing;
659 top += vspacing;
660 width -= hspacing * 2;
661 height -= vspacing * 2;
663 right = left + width - 1;
664 bottom = top + height - 1;
666 cy = (height + 1) / 2;
668 SetAPen(rp, pens[SHADOWPEN]);
670 for(i = 0; i < cy; i++)
672 RectFill(rp, left + (cy - i - 1) * width / cy,
673 top + i,
674 right - i * width / cy / 2,
675 top + i);
676 RectFill(rp, left + (cy - i - 1) * width / cy,
677 bottom - i,
678 right - i * width / cy / 2,
679 bottom - i);
681 break;
684 case UPIMAGE:
686 UWORD hspacing,vspacing;
687 WORD cx, i;
689 hspacing = HSPACING;
690 vspacing = VSPACING;
692 if (width <= 12)
694 hspacing = HSPACING_MIDDLE;
697 if (width <= 10)
699 hspacing = HSPACING_SMALL;
702 if (height <= 12)
704 vspacing = VSPACING_MIDDLE;
707 if (height <= 10)
709 vspacing = VSPACING_SMALL;
712 renderimageframe(rp, UPIMAGE, state, pens,
713 left, top, width, height, IntuitionBase);
714 left++;
715 top++;
716 right--;
717 bottom--;
718 width -= 2;
719 height -= 2;
721 SetAPen(rp, getbgpen(state, pens));
722 RectFill(rp, left, top, right, bottom);
724 left += hspacing;
725 top += vspacing;
726 width -= hspacing * 2;
727 height -= vspacing * 2;
729 right = left + width - 1;
730 bottom = top + height - 1;
732 cx = (width + 1) / 2;
734 SetAPen(rp, pens[SHADOWPEN]);
736 for(i = 0; i < cx; i++)
738 RectFill(rp, left + i,
739 top + (cx - i - 1) * height / cx,
740 left + i,
741 bottom - i * height / cx / 2);
742 RectFill(rp, right - i,
743 top + (cx - i - 1) * height / cx,
744 right - i,
745 bottom - i * height / cx / 2);
748 break;
751 case RIGHTIMAGE:
753 UWORD hspacing,vspacing;
754 WORD cy, i;
756 hspacing = HSPACING;
757 vspacing = VSPACING;
759 if (width <= 12)
761 hspacing = HSPACING_MIDDLE;
764 if (width <= 10)
766 hspacing = HSPACING_SMALL;
769 if (height <= 12)
771 vspacing = VSPACING_MIDDLE;
774 if (height <= 10)
776 vspacing = VSPACING_SMALL;
779 renderimageframe(rp, RIGHTIMAGE, state, pens,
780 left, top, width, height, IntuitionBase);
781 left++;
782 top++;
783 right--;
784 bottom--;
785 width -= 2;
786 height -= 2;
789 SetAPen(rp, getbgpen(state, pens));
790 RectFill(rp, left, top, right, bottom);
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 cy = (height + 1) / 2;
802 SetAPen(rp, pens[SHADOWPEN]);
804 for(i = 0; i < cy; i++)
806 RectFill(rp, left + i * width / cy / 2,
807 top + i,
808 right - (cy - i - 1) * width / cy,
809 top + i);
810 RectFill(rp, left + i * width / cy / 2,
811 bottom - i,
812 right - (cy - i - 1) * width / cy,
813 bottom - i);
815 break;
818 case DOWNIMAGE:
820 UWORD hspacing,vspacing;
821 WORD cx, i;
823 hspacing = HSPACING;
824 vspacing = VSPACING;
826 if (width <= 12)
828 hspacing = HSPACING_MIDDLE;
831 if (width <= 10)
833 hspacing = HSPACING_SMALL;
836 if (height <= 12)
838 vspacing = VSPACING_MIDDLE;
841 if (height <= 10)
843 vspacing = VSPACING_SMALL;
846 renderimageframe(rp, DOWNIMAGE, state, pens,
847 left, top, width, height, IntuitionBase);
848 left++;
849 top++;
850 right--;
851 bottom--;
852 width -= 2;
853 height -= 2;
855 SetAPen(rp, getbgpen(state, pens));
856 RectFill(rp, left, top, right, bottom);
858 left += hspacing;
859 top += vspacing;
860 width -= hspacing * 2;
861 height -= vspacing * 2;
863 right = left + width - 1;
864 bottom = top + height - 1;
866 cx = (width + 1) / 2;
868 SetAPen(rp, pens[SHADOWPEN]);
870 for(i = 0; i < cx; i++)
872 RectFill(rp, left + i,
873 top + i * height / cx / 2,
874 left + i,
875 bottom - (cx - i - 1) * height / cx);
876 RectFill(rp, right - i,
877 top + i * height / cx / 2,
878 right - i,
879 bottom - (cx - i - 1) * height / cx);
882 break;
886 default:
887 return FALSE;
890 return TRUE;
893 /**************************************************************************************************/
895 static void findtitlearea(struct Window *win, LONG *left, LONG *right)
897 struct Gadget *g;
899 *left = 0;
900 *right = win->Width - 1;
902 for (g = win->FirstGadget; g; g = g->NextGadget)
904 if (g->Activation & GACT_TOPBORDER && g != (struct Gadget *)IW(win)->sysgads[DRAGBAR])
906 if (!(g->Flags & GFLG_RELRIGHT))
908 if (g->LeftEdge + g->Width > *left)
909 *left = g->LeftEdge + g->Width;
911 else
913 if (g->LeftEdge + win->Width - 1 - 1 < *right)
914 *right = g->LeftEdge + win->Width - 1 - 1;
921 /**************************************************************************************************/
923 IPTR WinDecorClass__WDM_DRAW_WINBORDER(Class *cl, Object *obj, struct wdpDrawWinBorder *msg)
925 struct windecor_data *data = INST_DATA(cl, obj);
926 struct RastPort *rp = msg->wdp_RPort;
927 struct Window *window = msg->wdp_Window;
928 UWORD *pens = DRI(data->dri)->dri_Pens;
929 LONG left, right;
931 SetDrMd(rp, JAM1);
932 SetAPen(rp, pens[SHINEPEN]);
934 if (window->BorderTop > 0)
936 /* Outer shine edge on top side */
938 CheckRectFill(rp, 0, 0, window->Width - 1, 0, IntuitionBase);
941 if (!(msg->wdp_Flags & WDF_DWB_TOP_ONLY))
943 if (window->BorderLeft > 0)
945 /* Outer shine edge on left side */
947 CheckRectFill(rp, 0, 0, 0, window->Height - 1, IntuitionBase);
950 if (window->BorderRight > 1)
952 /* Inner shine edge on right side */
954 CheckRectFill(rp,
955 window->Width - window->BorderRight, window->BorderTop,
956 window->Width - window->BorderRight, window->Height - window->BorderBottom,
957 IntuitionBase);
960 if (window->BorderBottom > 1)
962 /* Inner shine edge on bottom side */
964 CheckRectFill(rp,
965 window->BorderLeft, window->Height - window->BorderBottom,
966 window->Width - window->BorderRight, window->Height - window->BorderBottom,
967 IntuitionBase);
971 SetAPen(rp, pens[SHADOWPEN]);
973 if (!(msg->wdp_Flags & WDF_DWB_TOP_ONLY))
975 if (window->BorderRight > 0)
977 /* Outer shadow edge on right side */
979 CheckRectFill(rp, window->Width - 1, 1,
980 window->Width - 1, window->Height - 1, IntuitionBase);
983 if (window->BorderBottom > 0)
985 /* Outer shadow edge on bottom side */
987 CheckRectFill(rp, 1, window->Height - 1,
988 window->Width - 1, window->Height - 1, IntuitionBase);
991 if (window->BorderLeft > 1)
993 /* Inner shadow edge on left side */
995 CheckRectFill(rp, window->BorderLeft - 1, window->BorderTop - 1,
996 window->BorderLeft - 1, window->Height - window->BorderBottom,
997 IntuitionBase);
1002 if (window->BorderTop > 1)
1004 /* Inner shadow edge on top side */
1006 CheckRectFill(rp, window->BorderLeft - 1, window->BorderTop - 1,
1007 window->Width - window->BorderRight, window->BorderTop - 1,
1008 IntuitionBase);
1011 SetAPen(rp, pens[(window->Flags & WFLG_WINDOWACTIVE) ? FILLPEN : BACKGROUNDPEN]);
1013 if (window->BorderTop > 2)
1015 /* Fill on top side */
1017 CheckRectFill(rp, 1, 1, window->Width - 2, window->BorderTop - 2, IntuitionBase);
1020 if (!(msg->wdp_Flags & WDF_DWB_TOP_ONLY))
1022 if (window->BorderLeft > 2)
1024 /* Fill on left side */
1026 CheckRectFill(rp, 1, 1, window->BorderLeft - 2, window->Height - 2, IntuitionBase);
1030 if (window->BorderRight > 2)
1032 /* Fill on right side */
1034 CheckRectFill(rp, window->Width - window->BorderRight + 1, 1,
1035 window->Width - 2, window->Height - 2, IntuitionBase);
1038 if (window->BorderBottom > 2)
1040 /* Fill on bottom side */
1042 CheckRectFill(rp, 1, window->Height - window->BorderBottom + 1,
1043 window->Width - 2, window->Height - 2, IntuitionBase);
1047 findtitlearea(window, &left, &right);
1049 if (left != 0)
1051 /* Left edge of title area */
1053 SetAPen(rp, pens[SHINEPEN]);
1054 Move(rp, left, 1);
1055 Draw(rp, left, window->BorderTop - 2);
1058 if (right != window->Width - 1)
1060 /* Right edges of title area */
1062 SetAPen(rp, pens[SHADOWPEN]);
1063 Move(rp, right, 1);
1064 Draw(rp, right, window->BorderTop - 2);
1067 return TRUE;
1070 /**************************************************************************************************/
1072 IPTR WinDecorClass__WDM_DRAW_WINTITLE(Class *cl, Object *obj, struct wdpDrawWinTitle *msg)
1074 struct windecor_data *data = INST_DATA(cl, obj);
1075 struct RastPort *rp = msg->wdp_RPort;
1076 struct Window *window = msg->wdp_Window;
1077 UWORD *pens = DRI(data->dri)->dri_Pens;
1078 LONG right, left;
1080 findtitlearea(window, &left, &right);
1082 SetDrMd(rp, JAM1);
1083 SetAPen(rp, pens[(window->Flags & WFLG_WINDOWACTIVE) ? FILLPEN : BACKGROUNDPEN]);
1084 CheckRectFill(rp, left + 1, 1, right - 1, window->BorderTop - 2, IntuitionBase);
1086 if (right - left > 6)
1088 ULONG textlen, titlelen, textpixellen;
1089 struct TextExtent te;
1091 SetFont(rp, DRI(data->dri)->dri_Font);
1093 titlelen = strlen(window->Title);
1094 textlen = TextFit(rp
1095 , window->Title
1096 , titlelen
1097 , &te
1098 , NULL
1100 , right - left - 6
1101 , window->BorderTop - 2);
1102 if (textlen)
1104 textpixellen = te.te_Extent.MaxX - te.te_Extent.MinX + 1;
1106 switch(msg->wdp_TitleAlign)
1108 case WD_DWTA_CENTER:
1109 if (textlen == titlelen)
1111 left = (left + right + 1 - textpixellen) / 2;
1113 else
1115 left = left + 3;
1117 break;
1119 case WD_DWTA_RIGHT:
1120 if (textlen == titlelen)
1122 left = right - textpixellen;
1124 else
1126 left = left + 3;
1128 break;
1130 default:
1131 case WD_DWTA_LEFT:
1132 left = left + 3;
1133 break;
1137 SetAPen(rp, pens[(window->Flags & WFLG_WINDOWACTIVE) ? FILLTEXTPEN : TEXTPEN]);
1139 Move(rp, left, DRI(data->dri)->dri_Font->tf_Baseline + 2);
1140 Text(rp, window->Title, textlen);
1144 return TRUE;
1147 /**************************************************************************************************/
1149 IPTR WinDecorClass__WDM_LAYOUT_BORDERGADGETS(Class *cl, Object *obj, struct wdpLayoutBorderGadgets *msg)
1151 //struct windecor_data *data = INST_DATA(cl, obj);
1152 //struct Window *window = msg->wdp_Window;
1153 struct Gadget *gadget = msg->wdp_Gadgets;
1155 while(gadget)
1157 switch(gadget->GadgetType & GTYP_SYSTYPEMASK)
1159 case GTYP_CLOSE:
1160 gadget->LeftEdge = 0;
1161 gadget->Width = gadget->Height;
1162 gadget->Flags &= ~(GFLG_RELRIGHT | GFLG_RELWIDTH);
1163 break;
1165 case GTYP_WDEPTH:
1166 gadget->LeftEdge = -gadget->Height + 1;
1167 gadget->Width = gadget->Height;
1168 gadget->Flags &= ~GFLG_RELWIDTH;
1169 gadget->Flags |= GFLG_RELRIGHT;
1170 break;
1172 case GTYP_WZOOM:
1173 gadget->LeftEdge = -gadget->Height * 2 + 1;
1174 gadget->Width = gadget->Height;
1175 gadget->Flags &= ~GFLG_RELWIDTH;
1176 gadget->Flags |= GFLG_RELRIGHT;
1177 break;
1179 case GTYP_WDRAGGING:
1180 gadget->LeftEdge = 0;
1181 gadget->Width = 0;
1182 gadget->Flags &= ~GFLG_RELRIGHT;
1183 gadget->Flags |= GFLG_RELWIDTH;
1184 break;
1187 if (msg->wdp_Flags & WDF_LBG_MULTIPLE)
1189 gadget = gadget->NextGadget;
1191 else
1193 gadget = NULL;
1197 return TRUE;
1200 /**************************************************************************************************/
1202 IPTR WinDecorClass__WDM_DRAW_BORDERPROPBACK(Class *cl, Object *obj, struct wdpDrawBorderPropBack *msg)
1204 struct windecor_data *data = INST_DATA(cl, obj);
1205 struct Window *window = msg->wdp_Window;
1206 struct RastPort *rp = msg->wdp_RPort;
1207 struct Gadget *gadget = msg->wdp_Gadget;
1208 struct Rectangle *r = msg->wdp_RenderRect;
1209 struct PropInfo *pi = ((struct PropInfo *)gadget->SpecialInfo);
1210 UWORD *pens = DRI(data->dri)->dri_Pens;
1212 SetDrMd(rp, JAM2);
1214 if (pi->Flags & PROPNEWLOOK)
1216 static UWORD pattern[] = {0x5555,0xAAAA};
1218 SetAfPt(rp, pattern, 1);
1219 SetAPen(rp, pens[SHADOWPEN]);
1220 SetBPen(rp, pens[(window->Flags & WFLG_WINDOWACTIVE) ? FILLPEN : BACKGROUNDPEN]);
1221 RectFill(rp, r->MinX, r->MinY, r->MaxX, r->MaxY);
1222 SetAfPt(rp, NULL, 0);
1224 else
1226 SetAPen(rp, pens[BACKGROUNDPEN]);
1227 RectFill(rp, r->MinX, r->MinY, r->MaxX, r->MaxY);
1230 return TRUE;
1233 /**************************************************************************************************/
1235 IPTR WinDecorClass__WDM_DRAW_BORDERPROPKNOB(Class *cl, Object *obj, struct wdpDrawBorderPropKnob *msg)
1237 struct windecor_data *data = INST_DATA(cl, obj);
1238 struct Window *window = msg->wdp_Window;
1239 struct RastPort *rp = msg->wdp_RPort;
1240 struct Gadget *gadget = msg->wdp_Gadget;
1241 struct Rectangle *r = msg->wdp_RenderRect;
1242 struct PropInfo *pi = ((struct PropInfo *)gadget->SpecialInfo);
1243 UWORD *pens = DRI(data->dri)->dri_Pens;
1245 SetDrMd(rp, JAM2);
1247 if (pi->Flags & PROPBORDERLESS)
1249 SetAPen(rp, pens[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[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 } /* PROPBORDERLESS */
1271 else
1273 SetAPen(rp, pens[SHADOWPEN]);
1275 if (pi->Flags & FREEHORIZ)
1277 /* black line at the left and at the right */
1279 RectFill(rp, r->MinX, r->MinY, r->MinX, r->MaxY);
1280 RectFill(rp, r->MaxX, r->MinY, r->MaxX, r->MaxY);
1282 r->MinX++;
1283 r->MaxX--;
1287 if (pi->Flags & FREEVERT)
1289 /* black line at the top and at the bottom */
1291 RectFill(rp, r->MinX, r->MinY, r->MaxX, r->MinY);
1292 RectFill(rp, r->MinX, r->MaxY, r->MaxX, r->MaxY);
1294 r->MinY++,
1295 r->MaxY--;
1299 } /* not PROPBORDERLESS */
1302 SetAPen(rp, pens[(window->Flags & WFLG_WINDOWACTIVE) ? FILLPEN : BACKGROUNDPEN]);
1304 /* interior */
1305 RectFill(rp, r->MinX, r->MinY, r->MaxX, r->MaxY);
1307 return TRUE;
1311 /**************************************************************************************************/