define __KERNEL_STRICT_NAMES to avoid inclusion of kernel types on systems that carry...
[cake.git] / rom / intuition / sysiclass_aros.c
blob3e51000788e210771ac6e8fe039713f3f6707da9
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$
5 */
7 /**************************************************************************************************/
9 #include <exec/types.h>
11 #include <proto/intuition.h>
12 #include <proto/layers.h>
13 #include <intuition/classes.h>
14 #include <intuition/classusr.h>
15 #include <intuition/imageclass.h>
16 #include <intuition/windecorclass.h>
17 #include <intuition/scrdecorclass.h>
18 #include <intuition/intuition.h>
19 #include <intuition/intuitionbase.h>
20 #include <intuition/extensions.h>
21 #include <intuition/screens.h>
23 #include <proto/graphics.h>
24 #include <graphics/rastport.h>
26 #include <proto/utility.h>
27 #include <utility/tagitem.h>
29 #include <proto/alib.h>
31 #include <aros/asmcall.h>
32 #include "intuition_intern.h"
33 #ifdef __MORPHOS__
34 #include "intuition_extend.h"
35 #endif
37 #include "gadgets.h" /* Some handy rendering funtions */
39 #define INTDRI(dri) ((struct IntDrawInfo *)(dri))
41 #if 0
42 extern BYTE *ibPrefs;
43 extern BYTE *ibSnapshot;
44 extern BYTE *ibSnapshotSel;
45 extern BYTE *ibPopupSel;
46 extern BYTE *ibPopup;
47 extern BYTE *ibIconify;
48 extern BYTE *ibIconifySel;
49 extern BYTE *ibLock;
50 extern BYTE *ibLockSel;
51 extern VOID DrawIB(struct RastPort *rp,BYTE *ib,LONG cx,LONG cy,struct IntuitionBase *IntuitionBase);
52 extern void DrawJUMP(struct RastPort *rp,ULONG state,LONG cx,LONG cy,struct IntuitionBase *IntuitionBase);
53 #endif
55 #undef DEBUG
56 #define DEBUG 0
57 #include <aros/debug.h>
59 /**************************************************************************************************/
61 #define DEFSIZE_WIDTH 14
62 #define DEFSIZE_HEIGHT 14
64 /**************************************************************************************************/
66 /* Some handy transparent base class object casting defines.
68 #define IM(o) ((struct Image *)o)
70 static UWORD getbgpen(ULONG state, UWORD *pens);
71 static UWORD getbgpen_gt(ULONG state, UWORD *pens);
72 static void renderimageframe(struct RastPort *rp, ULONG which, ULONG state, UWORD *pens,
73 WORD left, WORD top, WORD width, WORD height,
74 struct IntuitionBase *IntuitionBase);
76 #undef IntuitionBase
77 #define IntuitionBase ((struct IntuitionBase *)(cl->cl_UserData))
80 /**************************************************************************************************/
82 #define SYSIFLG_GADTOOLS 1
83 #define SYSIFLG_NOBORDER 2
85 /**************************************************************************************************/
87 /* Some handy drawing functions */
89 void draw_thick_line(Class *cl, struct RastPort *rport,
90 LONG x1, LONG y1, LONG x2, LONG y2,
91 UWORD thickness)
93 Move(rport, x1, y1);
94 Draw(rport, x2, y2);
95 /* Georg Steger */
96 Move(rport, x1 + 1, y1);
97 Draw(rport, x2 + 1, y2);
100 /**************************************************************************************************/
102 BOOL sysi_setnew(Class *cl, Object *obj, struct opSet *msg)
104 struct SysIData *data = INST_DATA(cl, obj);
105 struct TagItem *taglist, *tag;
106 struct TextFont *reffont = NULL;
107 int size = SYSISIZE_MEDRES;
108 BOOL unsupported = FALSE;
109 BOOL set_width = FALSE, set_height = FALSE;
111 taglist = msg->ops_AttrList;
112 while ((tag = NextTagItem((const struct TagItem **)&taglist)))
114 switch(tag->ti_Tag)
116 case IA_Width:
117 set_width = TRUE;
118 break;
120 case IA_Height:
121 set_height = TRUE;
122 break;
124 case SYSIA_DrawInfo:
125 data->dri = (struct DrawInfo *)tag->ti_Data;
126 reffont = data->dri->dri_Font;
127 break;
129 case SYSIA_Which:
130 data->type = tag->ti_Data;
132 D(bug("SYSIA_Which type: %d\n", data->type));
134 switch (tag->ti_Data)
136 #warning "if IA_Width, IA_Height was not specified sysiclass should choose size depending on drawinfo (screen resolution)"
138 case LEFTIMAGE:
139 case UPIMAGE:
140 case RIGHTIMAGE:
141 case DOWNIMAGE:
142 case CHECKIMAGE:
143 case MXIMAGE:
144 case DEPTHIMAGE:
145 case SDEPTHIMAGE:
146 case ZOOMIMAGE:
147 case CLOSEIMAGE:
148 case SIZEIMAGE:
149 case MENUCHECK:
150 case AMIGAKEY:
151 case ICONIFYIMAGE:
152 case LOCKIMAGE:
153 case JUMPIMAGE:
154 case MUIIMAGE:
155 case POPUPIMAGE:
156 case SNAPSHOTIMAGE:
157 case SUBMENUIMAGE:
158 break;
160 default:
161 unsupported = TRUE;
162 break;
164 break;
166 case SYSIA_ReferenceFont:
167 if (tag->ti_Data) reffont = (struct TextFont *)tag->ti_Data;
168 break;
170 case SYSIA_Size:
171 size = tag->ti_Data;
172 break;
174 /* private tags */
176 case SYSIA_WithBorder:
177 if (!tag->ti_Data)
179 data->flags |= SYSIFLG_NOBORDER;
181 break;
183 case SYSIA_Style:
184 if (tag->ti_Data == SYSISTYLE_GADTOOLS)
186 data->flags |= SYSIFLG_GADTOOLS;
188 break;
190 case SYSIA_UserBuffer:
191 data->userbuffer = tag->ti_Data;
192 break;
195 } /* switch(tag->ti_Tag) */
197 } /* while ((tag = NextTagItem(&taglist))) */
199 D(bug("dri: %p, unsupported: %d\n", data->dri, unsupported));
201 if ((!data->dri) || (unsupported))
202 return FALSE;
205 ULONG width = DEFSIZE_WIDTH, height = DEFSIZE_HEIGHT;
207 BOOL tc = (data->dri->dri_Flags & DRIF_DIRECTCOLOR);
209 if (data->type == SDEPTHIMAGE)
211 struct sdpGetDefSizeSysImage smsg;
213 smsg.MethodID = SDM_GETDEFSIZE_SYSIMAGE;
214 smsg.sdp_TrueColor = tc;
215 smsg.sdp_Which = data->type;
216 smsg.sdp_SysiSize = size;
217 smsg.sdp_ReferenceFont = reffont;
218 smsg.sdp_Width = &width;
219 smsg.sdp_Height = &height;
220 smsg.sdp_Flags = 0;
221 smsg.sdp_Dri = data->dri;
222 smsg.sdp_UserBuffer = 0;
224 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->ScrDecorObj, (Msg)&smsg);
227 else if ((data->type == AMIGAKEY) || (data->type == MENUCHECK) || (data->type == SUBMENUIMAGE))
229 struct mdpGetDefSizeSysImage mmsg;
231 mmsg.MethodID = MDM_GETDEFSIZE_SYSIMAGE;
232 mmsg.mdp_TrueColor = tc;
233 mmsg.mdp_Which = data->type;
234 mmsg.mdp_SysiSize = size;
235 mmsg.mdp_ReferenceFont = reffont;
236 mmsg.mdp_Width = &width;
237 mmsg.mdp_Height = &height;
238 mmsg.mdp_Flags = 0;
239 mmsg.mdp_Dri = data->dri;
240 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->MenuDecorObj, (Msg)&mmsg);
243 else
245 struct wdpGetDefSizeSysImage wmsg;
247 wmsg.MethodID = WDM_GETDEFSIZE_SYSIMAGE;
248 wmsg.wdp_TrueColor = tc;
249 wmsg.wdp_Which = data->type;
250 wmsg.wdp_SysiSize = size;
251 wmsg.wdp_ReferenceFont = reffont;
252 wmsg.wdp_Width = &width;
253 wmsg.wdp_Height = &height;
254 wmsg.wdp_Flags = 0;
255 wmsg.wdp_Dri = data->dri;
256 wmsg.wdp_UserBuffer = 0;
258 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->WinDecorObj, (Msg)&wmsg);
263 if (!set_width) IM(obj)->Width = width;
264 if (!set_height) IM(obj)->Height = height;
267 return TRUE;
270 /**************************************************************************************************/
272 Object *SysIClass__OM_NEW(Class *cl, Class *rootcl, struct opSet *msg)
274 struct SysIData *data;
275 Object *obj;
277 D(bug("sysi_new()\n"));
278 obj = (Object *)DoSuperMethodA(cl, (Object *)rootcl, (Msg)msg);
279 if (!obj)
280 return NULL;
282 D(bug("sysi_new,: obj=%p\n", obj));
284 data = INST_DATA(cl, obj);
285 data->type = 0;
286 data->dri = NULL;
287 data->frame = NULL;
288 data->flags = 0;
290 if (!sysi_setnew(cl, obj, (struct opSet *)msg))
292 STACKULONG method = OM_DISPOSE;
293 CoerceMethodA(cl, obj, (Msg)&method);
294 return NULL;
297 D(bug("sysi_setnew called successfully\n"));
299 switch (data->type)
302 case CHECKIMAGE:
304 struct TagItem tags[] =
306 {IA_FrameType, FRAME_BUTTON },
307 {IA_EdgesOnly, FALSE },
308 {TAG_MORE }
311 tags[2].ti_Data = (IPTR)msg->ops_AttrList;
313 data->frame = NewObjectA(NULL, FRAMEICLASS, tags);
314 if (!data->frame)
316 STACKULONG method = OM_DISPOSE;
317 CoerceMethodA(cl, obj, (Msg)&method);
318 return NULL;
320 break;
323 /* Just to prevent it from reaching default: */
324 case MXIMAGE:
325 case LEFTIMAGE:
326 case UPIMAGE:
327 case RIGHTIMAGE:
328 case DOWNIMAGE:
330 case SDEPTHIMAGE:
331 case DEPTHIMAGE:
332 case ZOOMIMAGE:
333 case CLOSEIMAGE:
334 case SIZEIMAGE:
336 case MENUCHECK:
337 case AMIGAKEY:
338 case SUBMENUIMAGE:
339 case ICONIFYIMAGE:
340 case LOCKIMAGE:
341 case MUIIMAGE:
342 case POPUPIMAGE:
343 case SNAPSHOTIMAGE:
344 case JUMPIMAGE:
345 break;
347 default:
349 STACKULONG method = OM_DISPOSE;
351 CoerceMethodA(cl, obj, (Msg)&method);
353 return NULL;
356 return obj;
359 /**************************************************************************************************/
361 /* Georg Steger
363 #define HSPACING 3
364 #define VSPACING 3
365 /* Ralph Schmidt
366 * heuristics for smaller arrows used in apps
367 * like filer
369 #define HSPACING_MIDDLE 2
370 #define VSPACING_MIDDLE 2
371 #define HSPACING_SMALL 1
372 #define VSPACING_SMALL 1
374 IPTR SysIClass__IM_DRAW(Class *cl, Object *obj, struct impDraw *msg)
376 struct SysIData *data = INST_DATA(cl, obj);
377 struct RastPort *rport = msg->imp_RPort;
378 struct Window *win = NULL;
379 WORD left = IM(obj)->LeftEdge + msg->imp_Offset.X;
380 WORD top = IM(obj)->TopEdge + msg->imp_Offset.Y;
381 UWORD width = IM(obj)->Width;
382 UWORD height = IM(obj)->Height;
383 WORD right = left + width - 1;
384 WORD bottom = top + height - 1;
385 struct wdpDrawSysImage wdecormsg;
386 struct sdpDrawSysImage sdecormsg;
387 struct mdpDrawSysImage mdecormsg;
389 BOOL tc = (data->dri->dri_Flags & DRIF_DIRECTCOLOR);
391 if (rport) if (rport->Layer) win = (struct Window *) rport->Layer->Window;
393 wdecormsg.MethodID = WDM_DRAW_SYSIMAGE;
394 wdecormsg.wdp_TrueColor = tc;
395 wdecormsg.wdp_RPort = rport;
396 wdecormsg.wdp_X = left;
397 wdecormsg.wdp_Y = top;
398 wdecormsg.wdp_Width = width;
399 wdecormsg.wdp_Height = height;
400 wdecormsg.wdp_Which = data->type;
401 wdecormsg.wdp_State = msg->imp_State;
402 wdecormsg.wdp_Flags = 0;
403 wdecormsg.wdp_Dri = data->dri;
404 wdecormsg.wdp_UserBuffer = (win == NULL) ? NULL : ((struct IntWindow *)win)->DecorUserBuffer;
406 sdecormsg.MethodID = SDM_DRAW_SYSIMAGE;
407 sdecormsg.sdp_TrueColor = tc;
408 sdecormsg.sdp_RPort = rport;
409 sdecormsg.sdp_X = left;
410 sdecormsg.sdp_Y = top;
411 sdecormsg.sdp_Width = width;
412 sdecormsg.sdp_Height = height;
413 sdecormsg.sdp_Which = data->type;
414 sdecormsg.sdp_State = msg->imp_State;
415 sdecormsg.sdp_Flags = 0;
416 sdecormsg.sdp_Dri = data->dri;
417 sdecormsg.sdp_UserBuffer = data->userbuffer;
419 mdecormsg.MethodID = MDM_DRAW_SYSIMAGE;
420 mdecormsg.mdp_TrueColor = tc;
421 mdecormsg.mdp_RPort = rport;
422 mdecormsg.mdp_X = left;
423 mdecormsg.mdp_Y = top;
424 mdecormsg.mdp_Width = width;
425 mdecormsg.mdp_Height = height;
426 mdecormsg.mdp_Which = data->type;
427 mdecormsg.mdp_State = msg->imp_State;
428 mdecormsg.mdp_Flags = 0;
429 mdecormsg.mdp_Dri = data->dri;
430 mdecormsg.mdp_UserBuffer = data->userbuffer;
432 SetDrMd(rport, JAM1);
434 switch(data->type)
436 case CHECKIMAGE:
438 WORD h_spacing = width / 4;
439 WORD v_spacing = height / 4;
441 /* Draw frame */
442 DrawImageState(rport, data->frame,
443 msg->imp_Offset.X, msg->imp_Offset.Y,
444 IDS_NORMAL, data->dri);
446 /* Draw checkmark (only if image is in selected state) */
447 if (msg->imp_State == IDS_SELECTED)
449 left += h_spacing;
450 right -= h_spacing;
451 width -= h_spacing * 2;
452 top += v_spacing;
453 bottom -= v_spacing;
454 height -= v_spacing * 2;
456 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
457 draw_thick_line(cl, rport, left, top + height / 3 , left, bottom, 0);
458 draw_thick_line(cl, rport, left + 1, bottom, right - 1, top, 0);
460 break;
463 case MXIMAGE:
465 BOOL selected = FALSE;
466 WORD col1 = SHINEPEN;
467 WORD col2 = SHADOWPEN;
469 if ((msg->imp_State == IDS_SELECTED) || (msg->imp_State == IDS_INACTIVESELECTED))
471 col1 = SHADOWPEN;
472 col2 = SHINEPEN;
473 selected = TRUE;
476 SetAPen(rport, data->dri->dri_Pens[BACKGROUNDPEN]);
477 RectFill(rport, left, top, right, bottom);
479 #if 0
480 /* THICK MX IMAGE */
482 SetAPen(rport, data->dri->dri_Pens[col1]);
483 RectFill(rport, left + 2, top, right - 3, top + 1);
484 RectFill(rport, left + 1, top + 2, left + 2, top + 3);
485 RectFill(rport, left, top + 4, left + 1, bottom - 4);
486 RectFill(rport, left + 1, bottom - 3, left + 2, bottom - 2);
487 RectFill(rport, left + 2, bottom - 1, left + 2, bottom);
489 SetAPen(rport, data->dri->dri_Pens[col2]);
490 RectFill(rport, right - 2, top, right - 2, top + 1);
491 RectFill(rport, right - 2, top + 2, right - 1, top + 3);
492 RectFill(rport, right - 1, top + 4, right, bottom - 4);
493 RectFill(rport, right - 2, bottom - 3, right - 1, bottom - 2);
494 RectFill(rport, left + 3, bottom - 1, right - 2, bottom);
496 if (selected)
498 left += 4;
499 right -= 4;
500 width -= 8;
501 top += 4;
502 bottom -= 4;
503 height -= 8;
505 SetAPen(rport, data->dri->dri_Pens[FILLPEN]);
506 if ((width >= 3) && (height >= 3))
508 RectFill(rport, left + 1, top, right - 1, top);
509 RectFill(rport, left, top + 1, right, bottom - 1);
510 RectFill(rport, left + 1, bottom, right - 1, bottom);
512 else
514 RectFill(rport, left, top, right, bottom);
517 #else
518 /* THIN MX IMAGE */
520 SetAPen(rport, data->dri->dri_Pens[col1]);
521 RectFill(rport, left + 3, top, right - 3, top);
522 WritePixel(rport, left + 2, top + 1);
523 RectFill(rport, left + 1, top + 2, left + 1, top + 3);
524 RectFill(rport, left, top + 4, left, bottom - 4);
525 RectFill(rport, left + 1, bottom - 3, left + 1, bottom - 2);
526 WritePixel(rport, left + 2, bottom - 1);
528 SetAPen(rport, data->dri->dri_Pens[col2]);
529 WritePixel(rport, right - 2, top + 1);
530 RectFill(rport, right - 1, top + 2, right - 1, top + 3);
531 RectFill(rport, right, top + 4, right, bottom - 4);
532 RectFill(rport, right - 1, bottom - 3, right - 1, bottom - 2);
533 WritePixel(rport, right - 2, bottom - 1);
534 RectFill(rport, left + 3, bottom, right - 3, bottom);
536 if (selected)
538 left += 3;
539 right -= 3;
540 width -= 6;
541 top += 3;
542 bottom -= 3;
543 height -= 6;
545 SetAPen(rport, data->dri->dri_Pens[FILLPEN]);
546 if ((width >= 5) && (height >= 5))
548 RectFill(rport, left, top + 2, left, bottom - 2);
549 RectFill(rport, left + 1, top + 1, left + 1, bottom - 1);
550 RectFill(rport, left + 2, top, right - 2, bottom);
551 RectFill(rport, right - 1, top + 1, right - 1, bottom - 1);
552 RectFill(rport, right, top + 2, right, bottom - 2);
554 else
556 RectFill(rport, left, top, right, bottom);
560 #endif
561 break;
564 case LEFTIMAGE:
566 UWORD hspacing,vspacing;
567 WORD cy;
569 if (!(data->flags & (SYSIFLG_NOBORDER | SYSIFLG_GADTOOLS)))
571 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->WinDecorObj, (Msg)&wdecormsg);
572 break;
575 hspacing = HSPACING;
576 vspacing = VSPACING;
578 if (width <= 12)
580 hspacing = HSPACING_MIDDLE;
583 if (width <= 10)
585 hspacing = HSPACING_SMALL;
588 if (height <= 12)
590 vspacing = VSPACING_MIDDLE;
593 if (height <= 10)
595 vspacing = VSPACING_SMALL;
598 if (!(data->flags & SYSIFLG_NOBORDER))
600 renderimageframe(rport, LEFTIMAGE, msg->imp_State, data->dri->dri_Pens,
601 left, top, width, height, IntuitionBase);
602 left++;
603 top++;
604 right--;
605 bottom--;
606 width -= 2;
607 height -= 2;
609 if (data->flags & SYSIFLG_GADTOOLS)
611 SetAPen(rport, getbgpen_gt(msg->imp_State, data->dri->dri_Pens));
612 RectFill(rport, left, top, right, bottom);
616 if (data->flags & SYSIFLG_GADTOOLS)
618 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
620 cy = height / 2;
622 Move(rport, left + width - 1 - hspacing, top + vspacing + 1);
623 Draw(rport, left + hspacing, top + height - cy);
624 Move(rport, left + width - 1 - hspacing, top + vspacing);
625 Draw(rport, left + hspacing, top + height - cy - 1);
627 Move(rport, left + width - 1 - hspacing, top + height - 1- vspacing - 1);
628 Draw(rport, left + hspacing, top + cy - 1);
629 Move(rport, left + width - 1 - hspacing, top + height - 1 - vspacing);
630 Draw(rport, left + hspacing, top + cy);
632 else
634 WORD i;
636 SetAPen(rport, getbgpen(msg->imp_State, data->dri->dri_Pens));
638 RectFill(rport, left, top, right, bottom);
640 left += hspacing;
641 top += vspacing;
642 width -= hspacing * 2;
643 height -= vspacing * 2;
645 right = left + width - 1;
646 bottom = top + height - 1;
648 cy = (height + 1) / 2;
650 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
652 for(i = 0; i < cy; i++)
654 RectFill(rport, left + (cy - i - 1) * width / cy,
655 top + i,
656 right - i * width / cy / 2,
657 top + i);
658 RectFill(rport, left + (cy - i - 1) * width / cy,
659 bottom - i,
660 right - i * width / cy / 2,
661 bottom - i);
665 break;
668 case UPIMAGE:
670 UWORD hspacing,vspacing;
671 WORD cx;
673 if (!(data->flags & (SYSIFLG_NOBORDER | SYSIFLG_GADTOOLS)))
675 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->WinDecorObj, (Msg)&wdecormsg);
676 break;
679 hspacing = HSPACING;
680 vspacing = VSPACING;
682 if (width <= 12)
684 hspacing = HSPACING_MIDDLE;
687 if (width <= 10)
689 hspacing = HSPACING_SMALL;
692 if (height <= 12)
694 vspacing = VSPACING_MIDDLE;
697 if (height <= 10)
699 vspacing = VSPACING_SMALL;
702 if (!(data->flags & SYSIFLG_NOBORDER))
704 renderimageframe(rport, UPIMAGE, msg->imp_State, data->dri->dri_Pens,
705 left, top, width, height, IntuitionBase);
706 left++;
707 top++;
708 right--;
709 bottom--;
710 width -= 2;
711 height -= 2;
713 if (data->flags & SYSIFLG_GADTOOLS)
715 SetAPen(rport, getbgpen_gt(msg->imp_State, data->dri->dri_Pens));
716 RectFill(rport, left, top, right, bottom);
721 if (data->flags & SYSIFLG_GADTOOLS)
723 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
725 cx = width / 2;
727 Move(rport, left + hspacing + 1, top + height - 1 - vspacing);
728 Draw(rport, left + width - cx, top + vspacing);
729 Move(rport, left + hspacing, top + height - 1 - vspacing);
730 Draw(rport, left + width - cx - 1, top + vspacing);
732 Move(rport, left + width - 1 - hspacing - 1, top + height - 1 - vspacing);
733 Draw(rport, left + cx - 1, top + vspacing);
734 Move(rport, left + width - 1 - hspacing, top + height - 1 - vspacing);
735 Draw(rport, left + cx, top + vspacing);
737 else
739 WORD i;
741 SetAPen(rport, getbgpen(msg->imp_State, data->dri->dri_Pens));
743 RectFill(rport, left, top, right, bottom);
745 left += hspacing;
746 top += vspacing;
747 width -= hspacing * 2;
748 height -= vspacing * 2;
750 right = left + width - 1;
751 bottom = top + height - 1;
753 cx = (width + 1) / 2;
755 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
757 for(i = 0; i < cx; i++)
759 RectFill(rport, left + i,
760 top + (cx - i - 1) * height / cx,
761 left + i,
762 bottom - i * height / cx / 2);
763 RectFill(rport, right - i,
764 top + (cx - i - 1) * height / cx,
765 right - i,
766 bottom - i * height / cx / 2);
770 break;
773 case RIGHTIMAGE:
775 UWORD hspacing,vspacing;
776 WORD cy;
778 if (!(data->flags & (SYSIFLG_NOBORDER | SYSIFLG_GADTOOLS)))
780 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->WinDecorObj, (Msg)&wdecormsg);
781 break;
784 hspacing = HSPACING;
785 vspacing = VSPACING;
787 if (width <= 12)
789 hspacing = HSPACING_MIDDLE;
792 if (width <= 10)
794 hspacing = HSPACING_SMALL;
797 if (height <= 12)
799 vspacing = VSPACING_MIDDLE;
802 if (height <= 10)
804 vspacing = VSPACING_SMALL;
807 if (!(data->flags & SYSIFLG_NOBORDER))
809 renderimageframe(rport, RIGHTIMAGE, msg->imp_State, data->dri->dri_Pens,
810 left, top, width, height, IntuitionBase);
811 left++;
812 top++;
813 right--;
814 bottom--;
815 width -= 2;
816 height -= 2;
818 if (data->flags & SYSIFLG_GADTOOLS)
820 SetAPen(rport, getbgpen_gt(msg->imp_State, data->dri->dri_Pens));
821 RectFill(rport, left, top, right, bottom);
826 if (data->flags & SYSIFLG_GADTOOLS)
828 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
830 cy = height / 2;
832 Move(rport, left + hspacing, top + vspacing + 1);
833 Draw(rport, left + width - 1 - hspacing, top + height - cy);
834 Move(rport, left + hspacing, top + vspacing);
835 Draw(rport, left + width - 1 - hspacing, top + height - cy - 1);
837 Move(rport, left + hspacing, top + height - 1- vspacing - 1);
838 Draw(rport, left + width - 1 - hspacing, top + cy - 1);
839 Move(rport, left + hspacing, top + height - 1 - vspacing);
840 Draw(rport, left + width - 1 - hspacing, top + cy);
843 else
845 WORD i;
847 SetAPen(rport, getbgpen(msg->imp_State, data->dri->dri_Pens));
849 RectFill(rport, left, top, right, bottom);
851 left += hspacing;
852 top += vspacing;
853 width -= hspacing * 2;
854 height -= vspacing * 2;
856 right = left + width - 1;
857 bottom = top + height - 1;
859 cy = (height + 1) / 2;
861 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
863 for(i = 0; i < cy; i++)
865 RectFill(rport, left + i * width / cy / 2,
866 top + i,
867 right - (cy - i - 1) * width / cy,
868 top + i);
869 RectFill(rport, left + i * width / cy / 2,
870 bottom - i,
871 right - (cy - i - 1) * width / cy,
872 bottom - i);
876 break;
879 case DOWNIMAGE:
881 UWORD hspacing,vspacing;
882 WORD cx;
884 if (!(data->flags & (SYSIFLG_NOBORDER | SYSIFLG_GADTOOLS)))
886 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->WinDecorObj, (Msg)&wdecormsg);
887 break;
890 hspacing = HSPACING;
891 vspacing = VSPACING;
893 if (width <= 12)
895 hspacing = HSPACING_MIDDLE;
898 if (width <= 10)
900 hspacing = HSPACING_SMALL;
903 if (height <= 12)
905 vspacing = VSPACING_MIDDLE;
908 if (height <= 10)
910 vspacing = VSPACING_SMALL;
913 if (!(data->flags & SYSIFLG_NOBORDER))
915 renderimageframe(rport, DOWNIMAGE, msg->imp_State, data->dri->dri_Pens,
916 left, top, width, height, IntuitionBase);
917 left++;
918 top++;
919 right--;
920 bottom--;
921 width -= 2;
922 height -= 2;
924 if (data->flags & SYSIFLG_GADTOOLS)
926 SetAPen(rport, getbgpen_gt(msg->imp_State, data->dri->dri_Pens));
927 RectFill(rport, left, top, right, bottom);
931 if (data->flags & SYSIFLG_GADTOOLS)
933 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
935 cx = width / 2;
937 Move(rport, left + hspacing + 1, top + vspacing);
938 Draw(rport, left + width - cx, top + height - 1 - vspacing);
939 Move(rport, left + hspacing, top + vspacing);
940 Draw(rport, left + width - cx - 1, top + height - 1 - vspacing);
942 Move(rport, left + width - 1 - hspacing - 1, top + vspacing);
943 Draw(rport, left + cx - 1, top + height - 1 - vspacing);
944 Move(rport, left + width - 1 - hspacing, top + vspacing);
945 Draw(rport, left + cx, top + height - 1 - vspacing);
947 else
949 WORD i;
951 SetAPen(rport, getbgpen(msg->imp_State, data->dri->dri_Pens));
953 RectFill(rport, left, top, right, bottom);
955 left += hspacing;
956 top += vspacing;
957 width -= hspacing * 2;
958 height -= vspacing * 2;
960 right = left + width - 1;
961 bottom = top + height - 1;
963 cx = (width + 1) / 2;
965 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
967 for(i = 0; i < cx; i++)
969 RectFill(rport, left + i,
970 top + i * height / cx / 2,
971 left + i,
972 bottom - (cx - i - 1) * height / cx);
973 RectFill(rport, right - i,
974 top + i * height / cx / 2,
975 right - i,
976 bottom - (cx - i - 1) * height / cx);
981 break;
984 case CLOSEIMAGE:
985 case ZOOMIMAGE:
986 case DEPTHIMAGE:
987 case SIZEIMAGE:
989 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->WinDecorObj, (Msg)&wdecormsg);
990 break;
993 case SDEPTHIMAGE:
995 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->ScrDecorObj, (Msg)&sdecormsg);
996 break;
999 case MENUCHECK:
1001 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->MenuDecorObj, (Msg)&mdecormsg);
1002 break;
1005 case AMIGAKEY:
1007 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->MenuDecorObj, (Msg)&mdecormsg);
1008 break;
1011 case SUBMENUIMAGE:
1013 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->MenuDecorObj, (Msg)&mdecormsg);
1014 break;
1017 /* MUI and other non-std images */
1018 case MUIIMAGE:
1019 case SNAPSHOTIMAGE:
1020 case POPUPIMAGE:
1021 case ICONIFYIMAGE:
1022 case LOCKIMAGE:
1024 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->WinDecorObj, (Msg)&wdecormsg);
1025 break;
1030 } /* switch (image type) */
1032 return (IPTR)0;
1035 IPTR SysIClass__OM_DISPOSE(Class *cl, Object *obj, Msg msg)
1037 struct SysIData *data = INST_DATA(cl, obj);
1039 DisposeObject(data->frame);
1040 return DoSuperMethodA(cl, obj, msg);
1043 IPTR SysIClass__OM_SET(Class *cl, Object *obj, Msg msg)
1045 struct SysIData *data = INST_DATA(cl, obj);
1047 if (data->frame)
1048 DoMethodA((Object *)data->frame, msg);
1049 return DoSuperMethodA(cl, obj, msg);
1052 /**************************************************************************************************/
1054 #undef IntuitionBase
1056 /**************************************************************************************************/
1058 static UWORD getbgpen(ULONG state, UWORD *pens)
1060 UWORD bg;
1062 switch (state)
1064 case IDS_NORMAL:
1065 case IDS_SELECTED:
1066 bg = pens[FILLPEN];
1067 break;
1069 default:
1070 bg = pens[BACKGROUNDPEN];
1071 break;
1074 return bg;
1077 /**************************************************************************************************/
1079 static UWORD getbgpen_gt(ULONG state, UWORD *pens)
1081 UWORD bg;
1083 switch (state)
1085 case IDS_SELECTED:
1086 case IDS_INACTIVESELECTED:
1087 bg = pens[FILLPEN];
1088 break;
1090 default:
1091 bg = pens[BACKGROUNDPEN];
1092 break;
1095 return bg;
1098 /**************************************************************************************************/
1100 static void renderimageframe(struct RastPort *rp, ULONG which, ULONG state, UWORD *pens,
1101 WORD left, WORD top, WORD width, WORD height,
1102 struct IntuitionBase *IntuitionBase)
1104 WORD right = left + width - 1;
1105 WORD bottom = top + height - 1;
1106 BOOL leftedgegodown = FALSE;
1107 BOOL topedgegoright = FALSE;
1109 switch(which)
1111 case CLOSEIMAGE:
1112 /* draw separator line at the right side */
1113 SetAPen(rp, pens[SHINEPEN]);
1114 RectFill(rp, right, top, right, bottom - 1);
1115 SetAPen(rp, pens[SHADOWPEN]);
1116 WritePixel(rp, right, bottom);
1118 right--;
1119 break;
1121 case ZOOMIMAGE:
1122 case DEPTHIMAGE:
1123 case SDEPTHIMAGE:
1124 /* draw separator line at the left side */
1125 SetAPen(rp, pens[SHINEPEN]);
1126 WritePixel(rp, left, top);
1127 SetAPen(rp, pens[SHADOWPEN]);
1128 RectFill(rp, left, top + 1, left, bottom);
1130 left++;
1131 break;
1133 case UPIMAGE:
1134 case DOWNIMAGE:
1135 leftedgegodown = TRUE;
1136 break;
1138 case LEFTIMAGE:
1139 case RIGHTIMAGE:
1140 topedgegoright = TRUE;
1141 break;
1144 if (left == 0) leftedgegodown = TRUE;
1145 if (top == 0) topedgegoright = TRUE;
1147 SetAPen(rp, pens[((state == IDS_SELECTED) || (state == IDS_INACTIVESELECTED)) ? SHADOWPEN : SHINEPEN]);
1149 /* left edge */
1150 RectFill(rp, left,
1151 top,
1152 left,
1153 bottom - (leftedgegodown ? 0 : 1));
1155 /* top edge */
1156 RectFill(rp, left + 1,
1157 top,
1158 right - (topedgegoright ? 0 : 1),
1159 top);
1161 SetAPen(rp, pens[((state == IDS_SELECTED) || (state == IDS_INACTIVESELECTED)) ? SHINEPEN : SHADOWPEN]);
1163 /* right edge */
1164 RectFill(rp, right,
1165 top + (topedgegoright ? 1 : 0),
1166 right,
1167 bottom);
1169 /* bottom edge */
1170 RectFill(rp, left + (leftedgegodown ? 1 : 0),
1171 bottom,
1172 right - 1,
1173 bottom);
1176 /**************************************************************************************************/