Minor fixes to comments.
[AROS.git] / rom / intuition / sysiclass.c
blobf35d383841b53cdb7736e6156eae5a2093f8ca1f
1 /*
2 Copyright 1995-2011, 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 /**************************************************************************************************/
78 #define SYSIFLG_GADTOOLS 1
79 #define SYSIFLG_NOBORDER 2
81 /**************************************************************************************************/
83 /* Some handy drawing functions */
85 void draw_thick_line(Class *cl, struct RastPort *rport,
86 LONG x1, LONG y1, LONG x2, LONG y2,
87 UWORD thickness)
89 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
90 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
91 Move(rport, x1, y1);
92 Draw(rport, x2, y2);
93 /* Georg Steger */
94 Move(rport, x1 + 1, y1);
95 Draw(rport, x2 + 1, y2);
98 /**************************************************************************************************/
100 BOOL sysi_setnew(Class *cl, Object *obj, struct opSet *msg)
102 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
103 struct Library *UtilityBase = GetPrivIBase(IntuitionBase)->UtilityBase;
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(&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 // FIXME: 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 = (APTR)tag->ti_Data;
192 break;
195 } /* switch(tag->ti_Tag) */
197 } /* while ((tag = NextTagItem(&taglist))) */
199 D(bug("dri: %p, unsupported: %d version: %d\n", data->dri, unsupported, data->dri->dri_Version));
201 if ((!data->dri) || (unsupported) || (data->dri->dri_Version != DRI_VERSION_AROS))
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 IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
275 struct SysIData *data;
276 Object *obj;
278 D(bug("sysi_new()\n"));
279 obj = (Object *)DoSuperMethodA(cl, (Object *)rootcl, (Msg)msg);
280 if (!obj)
281 return NULL;
283 D(bug("sysi_new,: obj=%p\n", obj));
285 data = INST_DATA(cl, obj);
286 data->type = 0;
287 data->dri = NULL;
288 data->frame = NULL;
289 data->flags = 0;
291 if (!sysi_setnew(cl, obj, (struct opSet *)msg))
293 STACKULONG method = OM_DISPOSE;
294 CoerceMethodA(cl, obj, (Msg)&method);
295 return NULL;
298 D(bug("sysi_setnew called successfully\n"));
300 switch (data->type)
303 case CHECKIMAGE:
305 struct TagItem tags[] =
307 {IA_FrameType, FRAME_BUTTON },
308 {IA_EdgesOnly, FALSE },
309 {TAG_MORE }
312 tags[2].ti_Data = (IPTR)msg->ops_AttrList;
314 data->frame = NewObjectA(NULL, FRAMEICLASS, tags);
315 if (!data->frame)
317 STACKULONG method = OM_DISPOSE;
318 CoerceMethodA(cl, obj, (Msg)&method);
319 return NULL;
321 break;
324 /* Just to prevent it from reaching default: */
325 case MXIMAGE:
326 case LEFTIMAGE:
327 case UPIMAGE:
328 case RIGHTIMAGE:
329 case DOWNIMAGE:
331 case SDEPTHIMAGE:
332 case DEPTHIMAGE:
333 case ZOOMIMAGE:
334 case CLOSEIMAGE:
335 case SIZEIMAGE:
337 case MENUCHECK:
338 case AMIGAKEY:
339 case SUBMENUIMAGE:
340 case ICONIFYIMAGE:
341 case LOCKIMAGE:
342 case MUIIMAGE:
343 case POPUPIMAGE:
344 case SNAPSHOTIMAGE:
345 case JUMPIMAGE:
346 break;
348 default:
350 STACKULONG method = OM_DISPOSE;
352 CoerceMethodA(cl, obj, (Msg)&method);
354 return NULL;
357 return obj;
360 /**************************************************************************************************/
362 /* Georg Steger
364 #define HSPACING 3
365 #define VSPACING 3
366 /* Ralph Schmidt
367 * heuristics for smaller arrows used in apps
368 * like filer
370 #define HSPACING_MIDDLE 2
371 #define VSPACING_MIDDLE 2
372 #define HSPACING_SMALL 1
373 #define VSPACING_SMALL 1
375 IPTR SysIClass__IM_DRAW(Class *cl, Object *obj, struct impDraw *msg)
377 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
378 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
379 struct SysIData *data = INST_DATA(cl, obj);
380 struct RastPort *rport = msg->imp_RPort;
381 struct Window *win = NULL;
382 WORD left = IM(obj)->LeftEdge + msg->imp_Offset.X;
383 WORD top = IM(obj)->TopEdge + msg->imp_Offset.Y;
384 UWORD width = IM(obj)->Width;
385 UWORD height = IM(obj)->Height;
386 WORD right = left + width - 1;
387 WORD bottom = top + height - 1;
388 struct wdpDrawSysImage wdecormsg;
389 struct sdpDrawSysImage sdecormsg;
390 struct mdpDrawSysImage mdecormsg;
392 BOOL tc = (data->dri->dri_Flags & DRIF_DIRECTCOLOR);
394 if (rport) if (rport->Layer) win = (struct Window *) rport->Layer->Window;
396 wdecormsg.MethodID = WDM_DRAW_SYSIMAGE;
397 wdecormsg.wdp_TrueColor = tc;
398 wdecormsg.wdp_RPort = rport;
399 wdecormsg.wdp_X = left;
400 wdecormsg.wdp_Y = top;
401 wdecormsg.wdp_Width = width;
402 wdecormsg.wdp_Height = height;
403 wdecormsg.wdp_Which = data->type;
404 wdecormsg.wdp_State = msg->imp_State;
405 wdecormsg.wdp_Flags = 0;
406 wdecormsg.wdp_Dri = data->dri;
407 wdecormsg.wdp_UserBuffer = (win == NULL) ? 0 : ((struct IntWindow *)win)->DecorUserBuffer;
409 sdecormsg.MethodID = SDM_DRAW_SYSIMAGE;
410 sdecormsg.sdp_TrueColor = tc;
411 sdecormsg.sdp_RPort = rport;
412 sdecormsg.sdp_X = left;
413 sdecormsg.sdp_Y = top;
414 sdecormsg.sdp_Width = width;
415 sdecormsg.sdp_Height = height;
416 sdecormsg.sdp_Which = data->type;
417 sdecormsg.sdp_State = msg->imp_State;
418 sdecormsg.sdp_Flags = 0;
419 sdecormsg.sdp_Dri = data->dri;
420 sdecormsg.sdp_UserBuffer = (IPTR)data->userbuffer;
422 mdecormsg.MethodID = MDM_DRAW_SYSIMAGE;
423 mdecormsg.mdp_TrueColor = tc;
424 mdecormsg.mdp_RPort = rport;
425 mdecormsg.mdp_X = left;
426 mdecormsg.mdp_Y = top;
427 mdecormsg.mdp_Width = width;
428 mdecormsg.mdp_Height = height;
429 mdecormsg.mdp_Which = data->type;
430 mdecormsg.mdp_State = msg->imp_State;
431 mdecormsg.mdp_Flags = 0;
432 mdecormsg.mdp_Dri = data->dri;
433 mdecormsg.mdp_UserBuffer = (IPTR)data->userbuffer;
435 SetDrMd(rport, JAM1);
437 switch(data->type)
439 case CHECKIMAGE:
441 WORD h_spacing = width / 4;
442 WORD v_spacing = height / 4;
444 /* Draw frame */
445 DrawImageState(rport, data->frame,
446 msg->imp_Offset.X, msg->imp_Offset.Y,
447 IDS_NORMAL, data->dri);
449 /* Draw checkmark (only if image is in selected state) */
450 if (msg->imp_State == IDS_SELECTED)
452 left += h_spacing;
453 right -= h_spacing;
454 width -= h_spacing * 2;
455 top += v_spacing;
456 bottom -= v_spacing;
457 height -= v_spacing * 2;
459 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
460 draw_thick_line(cl, rport, left, top + height / 3 , left, bottom, 0);
461 draw_thick_line(cl, rport, left + 1, bottom, right - 1, top, 0);
463 break;
466 case MXIMAGE:
468 BOOL selected = FALSE;
469 WORD col1 = SHINEPEN;
470 WORD col2 = SHADOWPEN;
472 if ((msg->imp_State == IDS_SELECTED) || (msg->imp_State == IDS_INACTIVESELECTED))
474 col1 = SHADOWPEN;
475 col2 = SHINEPEN;
476 selected = TRUE;
479 SetAPen(rport, data->dri->dri_Pens[BACKGROUNDPEN]);
480 RectFill(rport, left, top, right, bottom);
482 #if 0
483 /* THICK MX IMAGE */
485 SetAPen(rport, data->dri->dri_Pens[col1]);
486 RectFill(rport, left + 2, top, right - 3, top + 1);
487 RectFill(rport, left + 1, top + 2, left + 2, top + 3);
488 RectFill(rport, left, top + 4, left + 1, bottom - 4);
489 RectFill(rport, left + 1, bottom - 3, left + 2, bottom - 2);
490 RectFill(rport, left + 2, bottom - 1, left + 2, bottom);
492 SetAPen(rport, data->dri->dri_Pens[col2]);
493 RectFill(rport, right - 2, top, right - 2, top + 1);
494 RectFill(rport, right - 2, top + 2, right - 1, top + 3);
495 RectFill(rport, right - 1, top + 4, right, bottom - 4);
496 RectFill(rport, right - 2, bottom - 3, right - 1, bottom - 2);
497 RectFill(rport, left + 3, bottom - 1, right - 2, bottom);
499 if (selected)
501 left += 4;
502 right -= 4;
503 width -= 8;
504 top += 4;
505 bottom -= 4;
506 height -= 8;
508 SetAPen(rport, data->dri->dri_Pens[FILLPEN]);
509 if ((width >= 3) && (height >= 3))
511 RectFill(rport, left + 1, top, right - 1, top);
512 RectFill(rport, left, top + 1, right, bottom - 1);
513 RectFill(rport, left + 1, bottom, right - 1, bottom);
515 else
517 RectFill(rport, left, top, right, bottom);
520 #else
521 /* THIN MX IMAGE */
523 SetAPen(rport, data->dri->dri_Pens[col1]);
524 RectFill(rport, left + 3, top, right - 3, top);
525 WritePixel(rport, left + 2, top + 1);
526 RectFill(rport, left + 1, top + 2, left + 1, top + 3);
527 RectFill(rport, left, top + 4, left, bottom - 4);
528 RectFill(rport, left + 1, bottom - 3, left + 1, bottom - 2);
529 WritePixel(rport, left + 2, bottom - 1);
531 SetAPen(rport, data->dri->dri_Pens[col2]);
532 WritePixel(rport, right - 2, top + 1);
533 RectFill(rport, right - 1, top + 2, right - 1, top + 3);
534 RectFill(rport, right, top + 4, right, bottom - 4);
535 RectFill(rport, right - 1, bottom - 3, right - 1, bottom - 2);
536 WritePixel(rport, right - 2, bottom - 1);
537 RectFill(rport, left + 3, bottom, right - 3, bottom);
539 if (selected)
541 left += 3;
542 right -= 3;
543 width -= 6;
544 top += 3;
545 bottom -= 3;
546 height -= 6;
548 SetAPen(rport, data->dri->dri_Pens[FILLPEN]);
549 if ((width >= 5) && (height >= 5))
551 RectFill(rport, left, top + 2, left, bottom - 2);
552 RectFill(rport, left + 1, top + 1, left + 1, bottom - 1);
553 RectFill(rport, left + 2, top, right - 2, bottom);
554 RectFill(rport, right - 1, top + 1, right - 1, bottom - 1);
555 RectFill(rport, right, top + 2, right, bottom - 2);
557 else
559 RectFill(rport, left, top, right, bottom);
563 #endif
564 break;
567 case LEFTIMAGE:
569 UWORD hspacing,vspacing;
570 WORD cy;
572 if (!(data->flags & (SYSIFLG_NOBORDER | SYSIFLG_GADTOOLS)))
574 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->WinDecorObj, (Msg)&wdecormsg);
575 break;
578 hspacing = HSPACING;
579 vspacing = VSPACING;
581 if (width <= 12)
583 hspacing = HSPACING_MIDDLE;
586 if (width <= 10)
588 hspacing = HSPACING_SMALL;
591 if (height <= 12)
593 vspacing = VSPACING_MIDDLE;
596 if (height <= 10)
598 vspacing = VSPACING_SMALL;
601 if (!(data->flags & SYSIFLG_NOBORDER))
603 renderimageframe(rport, LEFTIMAGE, msg->imp_State, data->dri->dri_Pens,
604 left, top, width, height, IntuitionBase);
605 left++;
606 top++;
607 right--;
608 bottom--;
609 width -= 2;
610 height -= 2;
612 if (data->flags & SYSIFLG_GADTOOLS)
614 SetAPen(rport, getbgpen_gt(msg->imp_State, data->dri->dri_Pens));
615 RectFill(rport, left, top, right, bottom);
619 if (data->flags & SYSIFLG_GADTOOLS)
621 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
623 cy = height / 2;
625 Move(rport, left + width - 1 - hspacing, top + vspacing + 1);
626 Draw(rport, left + hspacing, top + height - cy);
627 Move(rport, left + width - 1 - hspacing, top + vspacing);
628 Draw(rport, left + hspacing, top + height - cy - 1);
630 Move(rport, left + width - 1 - hspacing, top + height - 1- vspacing - 1);
631 Draw(rport, left + hspacing, top + cy - 1);
632 Move(rport, left + width - 1 - hspacing, top + height - 1 - vspacing);
633 Draw(rport, left + hspacing, top + cy);
635 else
637 WORD i;
639 SetAPen(rport, getbgpen(msg->imp_State, data->dri->dri_Pens));
641 RectFill(rport, left, top, right, bottom);
643 left += hspacing;
644 top += vspacing;
645 width -= hspacing * 2;
646 height -= vspacing * 2;
648 right = left + width - 1;
649 bottom = top + height - 1;
651 cy = (height + 1) / 2;
653 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
655 for(i = 0; i < cy; i++)
657 RectFill(rport, left + (cy - i - 1) * width / cy,
658 top + i,
659 right - i * width / cy / 2,
660 top + i);
661 RectFill(rport, left + (cy - i - 1) * width / cy,
662 bottom - i,
663 right - i * width / cy / 2,
664 bottom - i);
668 break;
671 case UPIMAGE:
673 UWORD hspacing,vspacing;
674 WORD cx;
676 if (!(data->flags & (SYSIFLG_NOBORDER | SYSIFLG_GADTOOLS)))
678 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->WinDecorObj, (Msg)&wdecormsg);
679 break;
682 hspacing = HSPACING;
683 vspacing = VSPACING;
685 if (width <= 12)
687 hspacing = HSPACING_MIDDLE;
690 if (width <= 10)
692 hspacing = HSPACING_SMALL;
695 if (height <= 12)
697 vspacing = VSPACING_MIDDLE;
700 if (height <= 10)
702 vspacing = VSPACING_SMALL;
705 if (!(data->flags & SYSIFLG_NOBORDER))
707 renderimageframe(rport, UPIMAGE, msg->imp_State, data->dri->dri_Pens,
708 left, top, width, height, IntuitionBase);
709 left++;
710 top++;
711 right--;
712 bottom--;
713 width -= 2;
714 height -= 2;
716 if (data->flags & SYSIFLG_GADTOOLS)
718 SetAPen(rport, getbgpen_gt(msg->imp_State, data->dri->dri_Pens));
719 RectFill(rport, left, top, right, bottom);
724 if (data->flags & SYSIFLG_GADTOOLS)
726 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
728 cx = width / 2;
730 Move(rport, left + hspacing + 1, top + height - 1 - vspacing);
731 Draw(rport, left + width - cx, top + vspacing);
732 Move(rport, left + hspacing, top + height - 1 - vspacing);
733 Draw(rport, left + width - cx - 1, top + vspacing);
735 Move(rport, left + width - 1 - hspacing - 1, top + height - 1 - vspacing);
736 Draw(rport, left + cx - 1, top + vspacing);
737 Move(rport, left + width - 1 - hspacing, top + height - 1 - vspacing);
738 Draw(rport, left + cx, top + vspacing);
740 else
742 WORD i;
744 SetAPen(rport, getbgpen(msg->imp_State, data->dri->dri_Pens));
746 RectFill(rport, left, top, right, bottom);
748 left += hspacing;
749 top += vspacing;
750 width -= hspacing * 2;
751 height -= vspacing * 2;
753 right = left + width - 1;
754 bottom = top + height - 1;
756 cx = (width + 1) / 2;
758 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
760 for(i = 0; i < cx; i++)
762 RectFill(rport, left + i,
763 top + (cx - i - 1) * height / cx,
764 left + i,
765 bottom - i * height / cx / 2);
766 RectFill(rport, right - i,
767 top + (cx - i - 1) * height / cx,
768 right - i,
769 bottom - i * height / cx / 2);
773 break;
776 case RIGHTIMAGE:
778 UWORD hspacing,vspacing;
779 WORD cy;
781 if (!(data->flags & (SYSIFLG_NOBORDER | SYSIFLG_GADTOOLS)))
783 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->WinDecorObj, (Msg)&wdecormsg);
784 break;
787 hspacing = HSPACING;
788 vspacing = VSPACING;
790 if (width <= 12)
792 hspacing = HSPACING_MIDDLE;
795 if (width <= 10)
797 hspacing = HSPACING_SMALL;
800 if (height <= 12)
802 vspacing = VSPACING_MIDDLE;
805 if (height <= 10)
807 vspacing = VSPACING_SMALL;
810 if (!(data->flags & SYSIFLG_NOBORDER))
812 renderimageframe(rport, RIGHTIMAGE, msg->imp_State, data->dri->dri_Pens,
813 left, top, width, height, IntuitionBase);
814 left++;
815 top++;
816 right--;
817 bottom--;
818 width -= 2;
819 height -= 2;
821 if (data->flags & SYSIFLG_GADTOOLS)
823 SetAPen(rport, getbgpen_gt(msg->imp_State, data->dri->dri_Pens));
824 RectFill(rport, left, top, right, bottom);
829 if (data->flags & SYSIFLG_GADTOOLS)
831 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
833 cy = height / 2;
835 Move(rport, left + hspacing, top + vspacing + 1);
836 Draw(rport, left + width - 1 - hspacing, top + height - cy);
837 Move(rport, left + hspacing, top + vspacing);
838 Draw(rport, left + width - 1 - hspacing, top + height - cy - 1);
840 Move(rport, left + hspacing, top + height - 1- vspacing - 1);
841 Draw(rport, left + width - 1 - hspacing, top + cy - 1);
842 Move(rport, left + hspacing, top + height - 1 - vspacing);
843 Draw(rport, left + width - 1 - hspacing, top + cy);
846 else
848 WORD i;
850 SetAPen(rport, getbgpen(msg->imp_State, data->dri->dri_Pens));
852 RectFill(rport, left, top, right, bottom);
854 left += hspacing;
855 top += vspacing;
856 width -= hspacing * 2;
857 height -= vspacing * 2;
859 right = left + width - 1;
860 bottom = top + height - 1;
862 cy = (height + 1) / 2;
864 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
866 for(i = 0; i < cy; i++)
868 RectFill(rport, left + i * width / cy / 2,
869 top + i,
870 right - (cy - i - 1) * width / cy,
871 top + i);
872 RectFill(rport, left + i * width / cy / 2,
873 bottom - i,
874 right - (cy - i - 1) * width / cy,
875 bottom - i);
879 break;
882 case DOWNIMAGE:
884 UWORD hspacing,vspacing;
885 WORD cx;
887 if (!(data->flags & (SYSIFLG_NOBORDER | SYSIFLG_GADTOOLS)))
889 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->WinDecorObj, (Msg)&wdecormsg);
890 break;
893 hspacing = HSPACING;
894 vspacing = VSPACING;
896 if (width <= 12)
898 hspacing = HSPACING_MIDDLE;
901 if (width <= 10)
903 hspacing = HSPACING_SMALL;
906 if (height <= 12)
908 vspacing = VSPACING_MIDDLE;
911 if (height <= 10)
913 vspacing = VSPACING_SMALL;
916 if (!(data->flags & SYSIFLG_NOBORDER))
918 renderimageframe(rport, DOWNIMAGE, msg->imp_State, data->dri->dri_Pens,
919 left, top, width, height, IntuitionBase);
920 left++;
921 top++;
922 right--;
923 bottom--;
924 width -= 2;
925 height -= 2;
927 if (data->flags & SYSIFLG_GADTOOLS)
929 SetAPen(rport, getbgpen_gt(msg->imp_State, data->dri->dri_Pens));
930 RectFill(rport, left, top, right, bottom);
934 if (data->flags & SYSIFLG_GADTOOLS)
936 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
938 cx = width / 2;
940 Move(rport, left + hspacing + 1, top + vspacing);
941 Draw(rport, left + width - cx, top + height - 1 - vspacing);
942 Move(rport, left + hspacing, top + vspacing);
943 Draw(rport, left + width - cx - 1, top + height - 1 - vspacing);
945 Move(rport, left + width - 1 - hspacing - 1, top + vspacing);
946 Draw(rport, left + cx - 1, top + height - 1 - vspacing);
947 Move(rport, left + width - 1 - hspacing, top + vspacing);
948 Draw(rport, left + cx, top + height - 1 - vspacing);
950 else
952 WORD i;
954 SetAPen(rport, getbgpen(msg->imp_State, data->dri->dri_Pens));
956 RectFill(rport, left, top, right, bottom);
958 left += hspacing;
959 top += vspacing;
960 width -= hspacing * 2;
961 height -= vspacing * 2;
963 right = left + width - 1;
964 bottom = top + height - 1;
966 cx = (width + 1) / 2;
968 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
970 for(i = 0; i < cx; i++)
972 RectFill(rport, left + i,
973 top + i * height / cx / 2,
974 left + i,
975 bottom - (cx - i - 1) * height / cx);
976 RectFill(rport, right - i,
977 top + i * height / cx / 2,
978 right - i,
979 bottom - (cx - i - 1) * height / cx);
984 break;
987 case CLOSEIMAGE:
988 case ZOOMIMAGE:
989 case DEPTHIMAGE:
990 case SIZEIMAGE:
992 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->WinDecorObj, (Msg)&wdecormsg);
993 break;
996 case SDEPTHIMAGE:
998 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->ScrDecorObj, (Msg)&sdecormsg);
999 break;
1002 case MENUCHECK:
1004 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->MenuDecorObj, (Msg)&mdecormsg);
1005 break;
1008 case AMIGAKEY:
1010 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->MenuDecorObj, (Msg)&mdecormsg);
1011 break;
1014 case SUBMENUIMAGE:
1016 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->MenuDecorObj, (Msg)&mdecormsg);
1017 break;
1020 /* MUI and other non-std images */
1021 case MUIIMAGE:
1022 case SNAPSHOTIMAGE:
1023 case POPUPIMAGE:
1024 case ICONIFYIMAGE:
1025 case LOCKIMAGE:
1027 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->WinDecorObj, (Msg)&wdecormsg);
1028 break;
1033 } /* switch (image type) */
1035 return (IPTR)0;
1038 IPTR SysIClass__OM_DISPOSE(Class *cl, Object *obj, Msg msg)
1040 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
1041 struct SysIData *data = INST_DATA(cl, obj);
1043 DisposeObject(data->frame);
1044 return DoSuperMethodA(cl, obj, msg);
1047 IPTR SysIClass__OM_SET(Class *cl, Object *obj, Msg msg)
1049 struct SysIData *data = INST_DATA(cl, obj);
1051 if (data->frame)
1052 DoMethodA((Object *)data->frame, msg);
1053 return DoSuperMethodA(cl, obj, msg);
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 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1105 WORD right = left + width - 1;
1106 WORD bottom = top + height - 1;
1107 BOOL leftedgegodown = FALSE;
1108 BOOL topedgegoright = FALSE;
1110 switch(which)
1112 case CLOSEIMAGE:
1113 /* draw separator line at the right side */
1114 SetAPen(rp, pens[SHINEPEN]);
1115 RectFill(rp, right, top, right, bottom - 1);
1116 SetAPen(rp, pens[SHADOWPEN]);
1117 WritePixel(rp, right, bottom);
1119 right--;
1120 break;
1122 case ZOOMIMAGE:
1123 case DEPTHIMAGE:
1124 case SDEPTHIMAGE:
1125 /* draw separator line at the left side */
1126 SetAPen(rp, pens[SHINEPEN]);
1127 WritePixel(rp, left, top);
1128 SetAPen(rp, pens[SHADOWPEN]);
1129 RectFill(rp, left, top + 1, left, bottom);
1131 left++;
1132 break;
1134 case UPIMAGE:
1135 case DOWNIMAGE:
1136 leftedgegodown = TRUE;
1137 break;
1139 case LEFTIMAGE:
1140 case RIGHTIMAGE:
1141 topedgegoright = TRUE;
1142 break;
1145 if (left == 0) leftedgegodown = TRUE;
1146 if (top == 0) topedgegoright = TRUE;
1148 SetAPen(rp, pens[((state == IDS_SELECTED) || (state == IDS_INACTIVESELECTED)) ? SHADOWPEN : SHINEPEN]);
1150 /* left edge */
1151 RectFill(rp, left,
1152 top,
1153 left,
1154 bottom - (leftedgegodown ? 0 : 1));
1156 /* top edge */
1157 RectFill(rp, left + 1,
1158 top,
1159 right - (topedgegoright ? 0 : 1),
1160 top);
1162 SetAPen(rp, pens[((state == IDS_SELECTED) || (state == IDS_INACTIVESELECTED)) ? SHINEPEN : SHADOWPEN]);
1164 /* right edge */
1165 RectFill(rp, right,
1166 top + (topedgegoright ? 1 : 0),
1167 right,
1168 bottom);
1170 /* bottom edge */
1171 RectFill(rp, left + (leftedgegodown ? 1 : 0),
1172 bottom,
1173 right - 1,
1174 bottom);
1177 /**************************************************************************************************/