Activate the screen depth gadget that is being clicked, rather than the
[AROS.git] / rom / intuition / sysiclass.c
blobfc4881baa315955ff3015774c912bb5ee694aadd
1 /*
2 Copyright 1995-2012, The AROS Development Team. All rights reserved.
3 Copyright 2001-2003, The MorphOS Development Team. All Rights Reserved.
4 $Id$
5 */
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 =
412 &((struct IntDrawInfo *)data->dri)->dri_Screen->RastPort;
413 sdecormsg.sdp_X = left;
414 sdecormsg.sdp_Y = top;
415 sdecormsg.sdp_Width = width;
416 sdecormsg.sdp_Height = height;
417 sdecormsg.sdp_Which = data->type;
418 sdecormsg.sdp_State = msg->imp_State;
419 sdecormsg.sdp_Flags = 0;
420 sdecormsg.sdp_Dri = data->dri;
421 sdecormsg.sdp_UserBuffer = (IPTR)data->userbuffer;
423 mdecormsg.MethodID = MDM_DRAW_SYSIMAGE;
424 mdecormsg.mdp_TrueColor = tc;
425 mdecormsg.mdp_RPort = rport;
426 mdecormsg.mdp_X = left;
427 mdecormsg.mdp_Y = top;
428 mdecormsg.mdp_Width = width;
429 mdecormsg.mdp_Height = height;
430 mdecormsg.mdp_Which = data->type;
431 mdecormsg.mdp_State = msg->imp_State;
432 mdecormsg.mdp_Flags = 0;
433 mdecormsg.mdp_Dri = data->dri;
434 mdecormsg.mdp_UserBuffer = (IPTR)data->userbuffer;
436 SetDrMd(rport, JAM1);
438 switch(data->type)
440 case CHECKIMAGE:
442 WORD h_spacing = width / 4;
443 WORD v_spacing = height / 4;
445 /* Draw frame */
446 DrawImageState(rport, data->frame,
447 msg->imp_Offset.X, msg->imp_Offset.Y,
448 IDS_NORMAL, data->dri);
450 /* Draw checkmark (only if image is in selected state) */
451 if (msg->imp_State == IDS_SELECTED)
453 left += h_spacing;
454 right -= h_spacing;
455 width -= h_spacing * 2;
456 top += v_spacing;
457 bottom -= v_spacing;
458 height -= v_spacing * 2;
460 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
461 draw_thick_line(cl, rport, left, top + height / 3 , left, bottom, 0);
462 draw_thick_line(cl, rport, left + 1, bottom, right - 1, top, 0);
464 break;
467 case MXIMAGE:
469 BOOL selected = FALSE;
470 WORD col1 = SHINEPEN;
471 WORD col2 = SHADOWPEN;
473 if ((msg->imp_State == IDS_SELECTED) || (msg->imp_State == IDS_INACTIVESELECTED))
475 col1 = SHADOWPEN;
476 col2 = SHINEPEN;
477 selected = TRUE;
480 SetAPen(rport, data->dri->dri_Pens[BACKGROUNDPEN]);
481 RectFill(rport, left, top, right, bottom);
483 #if 0
484 /* THICK MX IMAGE */
486 SetAPen(rport, data->dri->dri_Pens[col1]);
487 RectFill(rport, left + 2, top, right - 3, top + 1);
488 RectFill(rport, left + 1, top + 2, left + 2, top + 3);
489 RectFill(rport, left, top + 4, left + 1, bottom - 4);
490 RectFill(rport, left + 1, bottom - 3, left + 2, bottom - 2);
491 RectFill(rport, left + 2, bottom - 1, left + 2, bottom);
493 SetAPen(rport, data->dri->dri_Pens[col2]);
494 RectFill(rport, right - 2, top, right - 2, top + 1);
495 RectFill(rport, right - 2, top + 2, right - 1, top + 3);
496 RectFill(rport, right - 1, top + 4, right, bottom - 4);
497 RectFill(rport, right - 2, bottom - 3, right - 1, bottom - 2);
498 RectFill(rport, left + 3, bottom - 1, right - 2, bottom);
500 if (selected)
502 left += 4;
503 right -= 4;
504 width -= 8;
505 top += 4;
506 bottom -= 4;
507 height -= 8;
509 SetAPen(rport, data->dri->dri_Pens[FILLPEN]);
510 if ((width >= 3) && (height >= 3))
512 RectFill(rport, left + 1, top, right - 1, top);
513 RectFill(rport, left, top + 1, right, bottom - 1);
514 RectFill(rport, left + 1, bottom, right - 1, bottom);
516 else
518 RectFill(rport, left, top, right, bottom);
521 #else
522 /* THIN MX IMAGE */
524 SetAPen(rport, data->dri->dri_Pens[col1]);
525 RectFill(rport, left + 3, top, right - 3, top);
526 WritePixel(rport, left + 2, top + 1);
527 RectFill(rport, left + 1, top + 2, left + 1, top + 3);
528 RectFill(rport, left, top + 4, left, bottom - 4);
529 RectFill(rport, left + 1, bottom - 3, left + 1, bottom - 2);
530 WritePixel(rport, left + 2, bottom - 1);
532 SetAPen(rport, data->dri->dri_Pens[col2]);
533 WritePixel(rport, right - 2, top + 1);
534 RectFill(rport, right - 1, top + 2, right - 1, top + 3);
535 RectFill(rport, right, top + 4, right, bottom - 4);
536 RectFill(rport, right - 1, bottom - 3, right - 1, bottom - 2);
537 WritePixel(rport, right - 2, bottom - 1);
538 RectFill(rport, left + 3, bottom, right - 3, bottom);
540 if (selected)
542 left += 3;
543 right -= 3;
544 width -= 6;
545 top += 3;
546 bottom -= 3;
547 height -= 6;
549 SetAPen(rport, data->dri->dri_Pens[FILLPEN]);
550 if ((width >= 5) && (height >= 5))
552 RectFill(rport, left, top + 2, left, bottom - 2);
553 RectFill(rport, left + 1, top + 1, left + 1, bottom - 1);
554 RectFill(rport, left + 2, top, right - 2, bottom);
555 RectFill(rport, right - 1, top + 1, right - 1, bottom - 1);
556 RectFill(rport, right, top + 2, right, bottom - 2);
558 else
560 RectFill(rport, left, top, right, bottom);
564 #endif
565 break;
568 case LEFTIMAGE:
570 UWORD hspacing,vspacing;
571 WORD cy;
573 if (!(data->flags & (SYSIFLG_NOBORDER | SYSIFLG_GADTOOLS)))
575 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->WinDecorObj, (Msg)&wdecormsg);
576 break;
579 hspacing = HSPACING;
580 vspacing = VSPACING;
582 if (width <= 12)
584 hspacing = HSPACING_MIDDLE;
587 if (width <= 10)
589 hspacing = HSPACING_SMALL;
592 if (height <= 12)
594 vspacing = VSPACING_MIDDLE;
597 if (height <= 10)
599 vspacing = VSPACING_SMALL;
602 if (!(data->flags & SYSIFLG_NOBORDER))
604 renderimageframe(rport, LEFTIMAGE, msg->imp_State, data->dri->dri_Pens,
605 left, top, width, height, IntuitionBase);
606 left++;
607 top++;
608 right--;
609 bottom--;
610 width -= 2;
611 height -= 2;
613 if (data->flags & SYSIFLG_GADTOOLS)
615 SetAPen(rport, getbgpen_gt(msg->imp_State, data->dri->dri_Pens));
616 RectFill(rport, left, top, right, bottom);
620 if (data->flags & SYSIFLG_GADTOOLS)
622 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
624 cy = height / 2;
626 Move(rport, left + width - 1 - hspacing, top + vspacing + 1);
627 Draw(rport, left + hspacing, top + height - cy);
628 Move(rport, left + width - 1 - hspacing, top + vspacing);
629 Draw(rport, left + hspacing, top + height - cy - 1);
631 Move(rport, left + width - 1 - hspacing, top + height - 1- vspacing - 1);
632 Draw(rport, left + hspacing, top + cy - 1);
633 Move(rport, left + width - 1 - hspacing, top + height - 1 - vspacing);
634 Draw(rport, left + hspacing, top + cy);
636 else
638 WORD i;
640 SetAPen(rport, getbgpen(msg->imp_State, data->dri->dri_Pens));
642 RectFill(rport, left, top, right, bottom);
644 left += hspacing;
645 top += vspacing;
646 width -= hspacing * 2;
647 height -= vspacing * 2;
649 right = left + width - 1;
650 bottom = top + height - 1;
652 cy = (height + 1) / 2;
654 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
656 for(i = 0; i < cy; i++)
658 RectFill(rport, left + (cy - i - 1) * width / cy,
659 top + i,
660 right - i * width / cy / 2,
661 top + i);
662 RectFill(rport, left + (cy - i - 1) * width / cy,
663 bottom - i,
664 right - i * width / cy / 2,
665 bottom - i);
669 break;
672 case UPIMAGE:
674 UWORD hspacing,vspacing;
675 WORD cx;
677 if (!(data->flags & (SYSIFLG_NOBORDER | SYSIFLG_GADTOOLS)))
679 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->WinDecorObj, (Msg)&wdecormsg);
680 break;
683 hspacing = HSPACING;
684 vspacing = VSPACING;
686 if (width <= 12)
688 hspacing = HSPACING_MIDDLE;
691 if (width <= 10)
693 hspacing = HSPACING_SMALL;
696 if (height <= 12)
698 vspacing = VSPACING_MIDDLE;
701 if (height <= 10)
703 vspacing = VSPACING_SMALL;
706 if (!(data->flags & SYSIFLG_NOBORDER))
708 renderimageframe(rport, UPIMAGE, msg->imp_State, data->dri->dri_Pens,
709 left, top, width, height, IntuitionBase);
710 left++;
711 top++;
712 right--;
713 bottom--;
714 width -= 2;
715 height -= 2;
717 if (data->flags & SYSIFLG_GADTOOLS)
719 SetAPen(rport, getbgpen_gt(msg->imp_State, data->dri->dri_Pens));
720 RectFill(rport, left, top, right, bottom);
725 if (data->flags & SYSIFLG_GADTOOLS)
727 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
729 cx = width / 2;
731 Move(rport, left + hspacing + 1, top + height - 1 - vspacing);
732 Draw(rport, left + width - cx, top + vspacing);
733 Move(rport, left + hspacing, top + height - 1 - vspacing);
734 Draw(rport, left + width - cx - 1, top + vspacing);
736 Move(rport, left + width - 1 - hspacing - 1, top + height - 1 - vspacing);
737 Draw(rport, left + cx - 1, top + vspacing);
738 Move(rport, left + width - 1 - hspacing, top + height - 1 - vspacing);
739 Draw(rport, left + cx, top + vspacing);
741 else
743 WORD i;
745 SetAPen(rport, getbgpen(msg->imp_State, data->dri->dri_Pens));
747 RectFill(rport, left, top, right, bottom);
749 left += hspacing;
750 top += vspacing;
751 width -= hspacing * 2;
752 height -= vspacing * 2;
754 right = left + width - 1;
755 bottom = top + height - 1;
757 cx = (width + 1) / 2;
759 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
761 for(i = 0; i < cx; i++)
763 RectFill(rport, left + i,
764 top + (cx - i - 1) * height / cx,
765 left + i,
766 bottom - i * height / cx / 2);
767 RectFill(rport, right - i,
768 top + (cx - i - 1) * height / cx,
769 right - i,
770 bottom - i * height / cx / 2);
774 break;
777 case RIGHTIMAGE:
779 UWORD hspacing,vspacing;
780 WORD cy;
782 if (!(data->flags & (SYSIFLG_NOBORDER | SYSIFLG_GADTOOLS)))
784 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->WinDecorObj, (Msg)&wdecormsg);
785 break;
788 hspacing = HSPACING;
789 vspacing = VSPACING;
791 if (width <= 12)
793 hspacing = HSPACING_MIDDLE;
796 if (width <= 10)
798 hspacing = HSPACING_SMALL;
801 if (height <= 12)
803 vspacing = VSPACING_MIDDLE;
806 if (height <= 10)
808 vspacing = VSPACING_SMALL;
811 if (!(data->flags & SYSIFLG_NOBORDER))
813 renderimageframe(rport, RIGHTIMAGE, msg->imp_State, data->dri->dri_Pens,
814 left, top, width, height, IntuitionBase);
815 left++;
816 top++;
817 right--;
818 bottom--;
819 width -= 2;
820 height -= 2;
822 if (data->flags & SYSIFLG_GADTOOLS)
824 SetAPen(rport, getbgpen_gt(msg->imp_State, data->dri->dri_Pens));
825 RectFill(rport, left, top, right, bottom);
830 if (data->flags & SYSIFLG_GADTOOLS)
832 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
834 cy = height / 2;
836 Move(rport, left + hspacing, top + vspacing + 1);
837 Draw(rport, left + width - 1 - hspacing, top + height - cy);
838 Move(rport, left + hspacing, top + vspacing);
839 Draw(rport, left + width - 1 - hspacing, top + height - cy - 1);
841 Move(rport, left + hspacing, top + height - 1- vspacing - 1);
842 Draw(rport, left + width - 1 - hspacing, top + cy - 1);
843 Move(rport, left + hspacing, top + height - 1 - vspacing);
844 Draw(rport, left + width - 1 - hspacing, top + cy);
847 else
849 WORD i;
851 SetAPen(rport, getbgpen(msg->imp_State, data->dri->dri_Pens));
853 RectFill(rport, left, top, right, bottom);
855 left += hspacing;
856 top += vspacing;
857 width -= hspacing * 2;
858 height -= vspacing * 2;
860 right = left + width - 1;
861 bottom = top + height - 1;
863 cy = (height + 1) / 2;
865 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
867 for(i = 0; i < cy; i++)
869 RectFill(rport, left + i * width / cy / 2,
870 top + i,
871 right - (cy - i - 1) * width / cy,
872 top + i);
873 RectFill(rport, left + i * width / cy / 2,
874 bottom - i,
875 right - (cy - i - 1) * width / cy,
876 bottom - i);
880 break;
883 case DOWNIMAGE:
885 UWORD hspacing,vspacing;
886 WORD cx;
888 if (!(data->flags & (SYSIFLG_NOBORDER | SYSIFLG_GADTOOLS)))
890 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->WinDecorObj, (Msg)&wdecormsg);
891 break;
894 hspacing = HSPACING;
895 vspacing = VSPACING;
897 if (width <= 12)
899 hspacing = HSPACING_MIDDLE;
902 if (width <= 10)
904 hspacing = HSPACING_SMALL;
907 if (height <= 12)
909 vspacing = VSPACING_MIDDLE;
912 if (height <= 10)
914 vspacing = VSPACING_SMALL;
917 if (!(data->flags & SYSIFLG_NOBORDER))
919 renderimageframe(rport, DOWNIMAGE, msg->imp_State, data->dri->dri_Pens,
920 left, top, width, height, IntuitionBase);
921 left++;
922 top++;
923 right--;
924 bottom--;
925 width -= 2;
926 height -= 2;
928 if (data->flags & SYSIFLG_GADTOOLS)
930 SetAPen(rport, getbgpen_gt(msg->imp_State, data->dri->dri_Pens));
931 RectFill(rport, left, top, right, bottom);
935 if (data->flags & SYSIFLG_GADTOOLS)
937 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
939 cx = width / 2;
941 Move(rport, left + hspacing + 1, top + vspacing);
942 Draw(rport, left + width - cx, top + height - 1 - vspacing);
943 Move(rport, left + hspacing, top + vspacing);
944 Draw(rport, left + width - cx - 1, top + height - 1 - vspacing);
946 Move(rport, left + width - 1 - hspacing - 1, top + vspacing);
947 Draw(rport, left + cx - 1, top + height - 1 - vspacing);
948 Move(rport, left + width - 1 - hspacing, top + vspacing);
949 Draw(rport, left + cx, top + height - 1 - vspacing);
951 else
953 WORD i;
955 SetAPen(rport, getbgpen(msg->imp_State, data->dri->dri_Pens));
957 RectFill(rport, left, top, right, bottom);
959 left += hspacing;
960 top += vspacing;
961 width -= hspacing * 2;
962 height -= vspacing * 2;
964 right = left + width - 1;
965 bottom = top + height - 1;
967 cx = (width + 1) / 2;
969 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
971 for(i = 0; i < cx; i++)
973 RectFill(rport, left + i,
974 top + i * height / cx / 2,
975 left + i,
976 bottom - (cx - i - 1) * height / cx);
977 RectFill(rport, right - i,
978 top + i * height / cx / 2,
979 right - i,
980 bottom - (cx - i - 1) * height / cx);
985 break;
988 case CLOSEIMAGE:
989 case ZOOMIMAGE:
990 case DEPTHIMAGE:
991 case SIZEIMAGE:
993 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->WinDecorObj, (Msg)&wdecormsg);
994 break;
997 case SDEPTHIMAGE:
999 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->ScrDecorObj, (Msg)&sdecormsg);
1000 break;
1003 case MENUCHECK:
1005 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->MenuDecorObj, (Msg)&mdecormsg);
1006 break;
1009 case AMIGAKEY:
1011 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->MenuDecorObj, (Msg)&mdecormsg);
1012 break;
1015 case SUBMENUIMAGE:
1017 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->MenuDecorObj, (Msg)&mdecormsg);
1018 break;
1021 /* MUI and other non-std images */
1022 case MUIIMAGE:
1023 case SNAPSHOTIMAGE:
1024 case POPUPIMAGE:
1025 case ICONIFYIMAGE:
1026 case LOCKIMAGE:
1028 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->WinDecorObj, (Msg)&wdecormsg);
1029 break;
1034 } /* switch (image type) */
1036 return (IPTR)0;
1039 IPTR SysIClass__OM_DISPOSE(Class *cl, Object *obj, Msg msg)
1041 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
1042 struct SysIData *data = INST_DATA(cl, obj);
1044 DisposeObject(data->frame);
1045 return DoSuperMethodA(cl, obj, msg);
1048 IPTR SysIClass__OM_SET(Class *cl, Object *obj, Msg msg)
1050 struct SysIData *data = INST_DATA(cl, obj);
1052 if (data->frame)
1053 DoMethodA((Object *)data->frame, msg);
1054 return DoSuperMethodA(cl, obj, msg);
1057 /**************************************************************************************************/
1059 static UWORD getbgpen(ULONG state, UWORD *pens)
1061 UWORD bg;
1063 switch (state)
1065 case IDS_NORMAL:
1066 case IDS_SELECTED:
1067 bg = pens[FILLPEN];
1068 break;
1070 default:
1071 bg = pens[BACKGROUNDPEN];
1072 break;
1075 return bg;
1078 /**************************************************************************************************/
1080 static UWORD getbgpen_gt(ULONG state, UWORD *pens)
1082 UWORD bg;
1084 switch (state)
1086 case IDS_SELECTED:
1087 case IDS_INACTIVESELECTED:
1088 bg = pens[FILLPEN];
1089 break;
1091 default:
1092 bg = pens[BACKGROUNDPEN];
1093 break;
1096 return bg;
1099 /**************************************************************************************************/
1101 static void renderimageframe(struct RastPort *rp, ULONG which, ULONG state, UWORD *pens,
1102 WORD left, WORD top, WORD width, WORD height,
1103 struct IntuitionBase *IntuitionBase)
1105 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1106 WORD right = left + width - 1;
1107 WORD bottom = top + height - 1;
1108 BOOL leftedgegodown = FALSE;
1109 BOOL topedgegoright = FALSE;
1111 switch(which)
1113 case CLOSEIMAGE:
1114 /* draw separator line at the right side */
1115 SetAPen(rp, pens[SHINEPEN]);
1116 RectFill(rp, right, top, right, bottom - 1);
1117 SetAPen(rp, pens[SHADOWPEN]);
1118 WritePixel(rp, right, bottom);
1120 right--;
1121 break;
1123 case ZOOMIMAGE:
1124 case DEPTHIMAGE:
1125 case SDEPTHIMAGE:
1126 /* draw separator line at the left side */
1127 SetAPen(rp, pens[SHINEPEN]);
1128 WritePixel(rp, left, top);
1129 SetAPen(rp, pens[SHADOWPEN]);
1130 RectFill(rp, left, top + 1, left, bottom);
1132 left++;
1133 break;
1135 case UPIMAGE:
1136 case DOWNIMAGE:
1137 leftedgegodown = TRUE;
1138 break;
1140 case LEFTIMAGE:
1141 case RIGHTIMAGE:
1142 topedgegoright = TRUE;
1143 break;
1146 if (left == 0) leftedgegodown = TRUE;
1147 if (top == 0) topedgegoright = TRUE;
1149 SetAPen(rp, pens[((state == IDS_SELECTED) || (state == IDS_INACTIVESELECTED)) ? SHADOWPEN : SHINEPEN]);
1151 /* left edge */
1152 RectFill(rp, left,
1153 top,
1154 left,
1155 bottom - (leftedgegodown ? 0 : 1));
1157 /* top edge */
1158 RectFill(rp, left + 1,
1159 top,
1160 right - (topedgegoright ? 0 : 1),
1161 top);
1163 SetAPen(rp, pens[((state == IDS_SELECTED) || (state == IDS_INACTIVESELECTED)) ? SHINEPEN : SHADOWPEN]);
1165 /* right edge */
1166 RectFill(rp, right,
1167 top + (topedgegoright ? 1 : 0),
1168 right,
1169 bottom);
1171 /* bottom edge */
1172 RectFill(rp, left + (leftedgegodown ? 1 : 0),
1173 bottom,
1174 right - 1,
1175 bottom);
1178 /**************************************************************************************************/