2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
3 Copyright © 2001-2003, The MorphOS Development Team. All Rights Reserved.
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/intuition.h>
17 #include <intuition/intuitionbase.h>
18 #include <intuition/screens.h>
20 #include <proto/graphics.h>
21 #include <proto/cybergraphics.h>
22 #include <graphics/rastport.h>
23 #include <cybergraphx/cybergraphics.h>
25 #include <proto/utility.h>
26 #include <utility/tagitem.h>
28 #include <proto/alib.h>
30 #include <aros/asmcall.h>
31 #include "intuition_intern.h"
32 #include "intuition_customize.h"
33 #include "intuition_extend.h"
34 #include "renderwindowframe.h"
36 #include "gadgets.h" /* Some handy rendering funtions */
38 #include "sysiclass.h"
40 extern ULONG
HookEntry();
44 #include <aros/debug.h>
46 /**************************************************************************************************/
48 #define DEFSIZE_WIDTH 14
49 #define DEFSIZE_HEIGHT 14
51 /**************************************************************************************************/
53 /* Some handy transparent base class object casting defines.
55 #define IM(o) ((struct Image *)o)
58 /**************************************************************************************************/
64 struct IntDrawInfo
*dri
;
67 struct Window
*window
;
70 #define SYSIFLG_GADTOOLS 1
71 #define SYSIFLG_NOBORDER 2
72 #define SYSIFLG_STDLOOK 16
73 #define SYSIFLG_WINDOWOK 32
75 void renderimageframe(struct RastPort
*rp
, ULONG which
, ULONG state
, UWORD
*pens
,
76 WORD left
, WORD top
, WORD width
, WORD height
,
77 struct IntuitionBase
*IntuitionBase
);
80 /**************************************************************************************************/
82 static UWORD
getbgpen(ULONG state
, UWORD
*pens
);
86 #define IntuitionBase ((struct IntuitionBase *)(cl->cl_UserData))
88 /* Some handy drawing functions */
90 void draw_thick_line(Class
*cl
, struct RastPort
*rport
,
91 LONG x1
, LONG y1
, LONG x2
, LONG y2
,
97 Move(rport
, x1
+ 1, y1
);
98 Draw(rport
, x2
+ 1, y2
);
101 /**************************************************************************************************/
103 BOOL
sysi_setnew(Class
*cl
, Object
*obj
, struct opSet
*msg
)
105 struct SysIData
*data
= INST_DATA(cl
, obj
);
106 struct TagItem
*taglist
, *tag
;
107 struct TextFont
*reffont
= NULL
;
108 int size
= SYSISIZE_MEDRES
;
109 int def_low_width
= DEFSIZE_WIDTH
, def_low_height
= DEFSIZE_HEIGHT
;
110 int def_med_width
= DEFSIZE_WIDTH
, def_med_height
= DEFSIZE_HEIGHT
;
111 int def_high_width
= DEFSIZE_WIDTH
, def_high_height
= DEFSIZE_HEIGHT
;
114 BOOL unsupported
= FALSE
;
115 BOOL set_width
= FALSE
, set_height
= FALSE
;
117 taglist
= msg
->ops_AttrList
;
118 while ((tag
= NextTagItem((struct TagItem
**)&taglist
)))
131 data
->dri
= (struct IntDrawInfo
*)tag
->ti_Data
;
132 reffont
= data
->dri
->dri_Font
;
136 data
->type
= tag
->ti_Data
;
138 D(bug("SYSIA_Which type: %d\n", data
->type
));
140 switch (tag
->ti_Data
)
143 #warning if IA_Width, IA_Height was not specified sysiclass should choose size depending on drawinfo (screen resolution)
164 case MENUTOGGLEIMAGE
:
174 case SYSIA_ReferenceFont
:
175 if (tag
->ti_Data
) reffont
= (struct TextFont
*)tag
->ti_Data
;
184 case SYSIA_WithBorder
:
185 if (tag
->ti_Data
== FALSE
)
187 data
->flags
|= SYSIFLG_NOBORDER
;
192 if (tag
->ti_Data
== SYSISTYLE_GADTOOLS
)
194 data
->flags
|= SYSIFLG_GADTOOLS
;
201 data
->window
= (struct Window
*)tag
->ti_Data
;
202 data
->flags
|= SYSIFLG_WINDOWOK
;
206 } /* switch(tag->ti_Tag) */
208 } /* while ((tag = NextTagItem(&taglist))) */
210 D(bug("dri: %p, unsupported: %d\n", data
->dri
, unsupported
));
212 if ((!data
->dri
) || (unsupported
))
224 def_high_height
= 22;
234 def_high_height
= 22;
274 def_high_height
= 10;
278 //def_low_width = reffont->tf_XSize * 3 / 2;
279 //jDc: what's wrong with 1:1 ratio?? ;)
280 def_low_width
= reffont
->tf_YSize
;
281 def_low_height
= reffont
->tf_YSize
;
282 size
= SYSISIZE_LOWRES
;
287 def_low_width
= reffont
->tf_XSize
* 2;
288 def_low_height
= reffont
->tf_YSize
;
290 def_low_width
= reffont
->tf_XSize
* 2;
291 def_low_height
= reffont
->tf_YSize
+ 1;
293 size
= SYSISIZE_LOWRES
;
296 case MENUTOGGLEIMAGE
:
298 def_low_width
= reffont
->tf_YSize
;
299 def_low_height
= reffont
->tf_YSize
;
300 size
= SYSISIZE_LOWRES
;
305 * We really need some aspect ratio here..this sucks
307 def_low_width
= reffont
->tf_XSize
* 3 - 1;
308 def_low_height
= reffont
->tf_YSize
+ 1;
309 size
= SYSISIZE_LOWRES
;
314 * We really need some aspect ratio here..this sucks
316 def_low_width
= 26;//reffont->tf_XSize * 2;
317 def_low_height
= reffont
->tf_YSize
+ 3;
318 size
= SYSISIZE_LOWRES
;
321 } /* switch(data->type) */
324 IM(obj
)->Width
= size
== SYSISIZE_LOWRES
? def_low_width
:
325 (size
== SYSISIZE_HIRES
? def_high_width
: def_med_width
);
327 IM(obj
)->Height
= size
== SYSISIZE_LOWRES
? def_low_height
:
328 (size
== SYSISIZE_HIRES
? def_high_height
: def_med_height
);
330 sysi_skinnew(cl
,obj
,set_width
,set_height
,IntuitionBase
);
335 /**************************************************************************************************/
337 Object
*sysi_new(Class
*cl
, Class
*rootcl
, struct opSet
*msg
)
339 struct SysIData
*data
;
342 D(bug("sysi_new()\n"));
343 obj
= (Object
*)DoSuperMethodA(cl
, (Object
*)rootcl
, (Msg
)msg
);
347 D(bug("sysi_new,: obj=%p\n", obj
));
349 data
= INST_DATA(cl
, obj
);
354 if (!sysi_setnew(cl
, obj
, (struct opSet
*)msg
))
356 ULONG method
= OM_DISPOSE
;
357 CoerceMethodA(cl
, obj
, (Msg
)&method
);
361 D(bug("sysi_setnew called successfully\n"));
367 struct TagItem tags
[] =
369 {IA_FrameType
, FRAME_BUTTON
},
370 {IA_EdgesOnly
, FALSE
},
374 tags
[2].ti_Data
= (IPTR
)msg
->ops_AttrList
;
375 data
->frame
= NewObjectA(NULL
, FRAMEICLASS
, tags
);
378 ULONG method
= OM_DISPOSE
;
379 CoerceMethodA(cl
, obj
, (Msg
)&method
);
385 /* Just to prevent it from reaching default: */
407 case MENUTOGGLEIMAGE
:
413 ULONG method
= OM_DISPOSE
;
414 CoerceMethodA(cl
, obj
, (Msg
)&method
);
422 /**************************************************************************************************/
429 * heuristics for smaller arrows used in apps
432 #define HSPACING_MIDDLE 2
433 #define VSPACING_MIDDLE 2
434 #define HSPACING_SMALL 1
435 #define VSPACING_SMALL 1
437 void sysi_draw(Class
*cl
, Object
*obj
, struct impDraw
*msg
)
439 struct SysIData
*data
= INST_DATA(cl
, obj
);
440 struct RastPort
*rport
= msg
->imp_RPort
;
441 WORD left
= IM(obj
)->LeftEdge
+ msg
->imp_Offset
.X
;
442 WORD top
= IM(obj
)->TopEdge
+ msg
->imp_Offset
.Y
;
443 UWORD width
= IM(obj
)->Width
;
444 UWORD height
= IM(obj
)->Height
;
445 WORD right
= left
+ width
- 1;
446 WORD bottom
= top
+ height
- 1;
447 struct sysiclassprefs
*sysiclassprefs
;
451 SetDrMd(rport
, JAM1
);
453 if (sysi_drawskin(cl
,obj
,msg
,IntuitionBase
)) return;
455 sysiclassprefs
= (struct sysiclassprefs
*)int_GetCustomPrefs(TYPE_SYSICLASS
,data
->dri
,IntuitionBase
);
461 WORD h_spacing
= width
/ 4;
462 WORD v_spacing
= height
/ 4;
465 DrawImageState(rport
, data
->frame
,
466 msg
->imp_Offset
.X
, msg
->imp_Offset
.Y
,
467 IDS_NORMAL
, (struct DrawInfo
*)data
->dri
);
469 /* Draw checkmark (only if image is in selected state) */
470 if (msg
->imp_State
== IDS_SELECTED
)
474 width
-= h_spacing
* 2;
477 height
-= v_spacing
* 2;
479 SetAPen(rport
, data
->dri
->dri_Pens
[SHADOWPEN
]);
482 draw_thick_line(cl
, rport
, left
, top
+ height
/2, left
+ width
/3, bottom
, 0);
483 draw_thick_line(cl
, rport
, left
+ width
/3, bottom
, right
- 2, top
, 0);
484 Move(rport
, right
-1 , top
);
485 Draw(rport
, right
, top
);
487 draw_thick_line(cl
, rport
, left
, top
+ height
/ 3 , left
, bottom
, 0);
488 draw_thick_line(cl
, rport
, left
+ 1, bottom
, right
- 1, top
, 0);
496 BOOL selected
= FALSE
;
497 WORD col1
= SHINEPEN
;
498 WORD col2
= SHADOWPEN
;
500 if ((msg
->imp_State
== IDS_SELECTED
) || (msg
->imp_State
== IDS_INACTIVESELECTED
))
507 SetAPen(rport
, data
->dri
->dri_Pens
[BACKGROUNDPEN
]);
508 RectFill(rport
, left
, top
, right
, bottom
);
513 SetAPen(rport
, data
->dri
->dri_Pens
[col1
]);
514 RectFill(rport
, left
+ 2, top
, right
- 3, top
+ 1);
515 RectFill(rport
, left
+ 1, top
+ 2, left
+ 2, top
+ 3);
516 RectFill(rport
, left
, top
+ 4, left
+ 1, bottom
- 4);
517 RectFill(rport
, left
+ 1, bottom
- 3, left
+ 2, bottom
- 2);
518 RectFill(rport
, left
+ 2, bottom
- 1, left
+ 2, bottom
);
520 SetAPen(rport
, data
->dri
->dri_Pens
[col2
]);
521 RectFill(rport
, right
- 2, top
, right
- 2, top
+ 1);
522 RectFill(rport
, right
- 2, top
+ 2, right
- 1, top
+ 3);
523 RectFill(rport
, right
- 1, top
+ 4, right
, bottom
- 4);
524 RectFill(rport
, right
- 2, bottom
- 3, right
- 1, bottom
- 2);
525 RectFill(rport
, left
+ 3, bottom
- 1, right
- 2, bottom
);
536 SetAPen(rport
, data
->dri
->dri_Pens
[FILLPEN
]);
537 if ((width
>= 3) && (height
>= 3))
539 RectFill(rport
, left
+ 1, top
, right
- 1, top
);
540 RectFill(rport
, left
, top
+ 1, right
, bottom
- 1);
541 RectFill(rport
, left
+ 1, bottom
, right
- 1, bottom
);
545 RectFill(rport
, left
, top
, right
, bottom
);
551 SetAPen(rport
, data
->dri
->dri_Pens
[col1
]);
552 RectFill(rport
, left
+ 3, top
, right
- 3, top
);
553 WritePixel(rport
, left
+ 2, top
+ 1);
554 RectFill(rport
, left
+ 1, top
+ 2, left
+ 1, top
+ 3);
555 RectFill(rport
, left
, top
+ 4, left
, bottom
- 4);
556 RectFill(rport
, left
+ 1, bottom
- 3, left
+ 1, bottom
- 2);
557 WritePixel(rport
, left
+ 2, bottom
- 1);
559 SetAPen(rport
, data
->dri
->dri_Pens
[col2
]);
560 WritePixel(rport
, right
- 2, top
+ 1);
561 RectFill(rport
, right
- 1, top
+ 2, right
- 1, top
+ 3);
562 RectFill(rport
, right
, top
+ 4, right
, bottom
- 4);
563 RectFill(rport
, right
- 1, bottom
- 3, right
- 1, bottom
- 2);
564 WritePixel(rport
, right
- 2, bottom
- 1);
565 RectFill(rport
, left
+ 3, bottom
, right
- 3, bottom
);
576 SetAPen(rport
, data
->dri
->dri_Pens
[FILLPEN
]);
577 if ((width
>= 5) && (height
>= 5))
579 RectFill(rport
, left
, top
+ 2, left
, bottom
- 2);
580 RectFill(rport
, left
+ 1, top
+ 1, left
+ 1, bottom
- 1);
581 RectFill(rport
, left
+ 2, top
, right
- 2, bottom
);
582 RectFill(rport
, right
- 1, top
+ 1, right
- 1, bottom
- 1);
583 RectFill(rport
, right
, top
+ 2, right
, bottom
- 2);
587 RectFill(rport
, left
, top
, right
, bottom
);
597 case MENUTOGGLEIMAGE
:
599 UWORD
*pens
= data
->dri
->dri_Pens
;
601 //#if MENUS_AMIGALOOK
602 // SetAPen(rport, pens[BARBLOCKPEN]);
604 // SetAPen(rport, pens[(msg->imp_State == IDS_SELECTED) ? FILLPEN : BACKGROUNDPEN]);
609 // /*EraseRect(rport,left,top,right,bottom);*/
610 // /*menutask will handle this!*/
614 // RectFill(rport,left, top, right, bottom);
617 SetAPen(rport
, pens
[BARDETAILPEN
]);
622 draw_thick_line(cl
, rport
, left
+ 1, top
+ height
/ 3 , left
+ 1, bottom
, 0);
623 draw_thick_line(cl
, rport
, left
+ 2, bottom
, right
- 2, top
, 0);
626 case MENUTOGGLEIMAGE
:
627 RectFill(rport
,left
,top
,left
+ width
- 1,top
);
628 RectFill(rport
,left
,top
+ height
- 1,left
+ width
- 1,top
+ height
- 1);
629 RectFill(rport
,left
,top
,left
,top
+ height
- 1);
630 RectFill(rport
,left
+ width
- 1, top
, left
+ width
- 1, top
+ height
-1);
631 left
++;top
++;width
-= 2; height
-=2;
632 if (msg
->imp_State
== IDS_SELECTED
)
634 draw_thick_line(cl
, rport
, left
+ 1, top
+ height
/ 3 , left
+ 1, bottom
, 0);
635 draw_thick_line(cl
, rport
, left
+ 2, bottom
, right
- 2, top
, 0);
640 Move(rport
,left
+ width
- 2, top
+ height
/2);
641 Draw(rport
,left
+ width
- 6, top
+ height
/2 - 2);
642 Move(rport
,left
+ width
- 2, top
+ height
/2);
643 Draw(rport
,left
+ width
- 6, top
+ height
/2 + 2);
652 //UWORD *pens = data->dri->dri_Pens;
654 int_RenderWindowFrame(data
->window
,left
,top
,width
,height
,data
->dri
,IntuitionBase
);
656 if (!(data
->flags
& SYSIFLG_NOBORDER
))
660 int_RenderWindowFrameBorder(data
->window
,left
,top
,width
,height
,data
->dri
,IntuitionBase
);
664 renderimageframe(rport
, data
->type
, msg
->imp_State
, data
->dri
->dri_Pens
,
665 left
, top
, width
, height
, IntuitionBase
);
677 DrawIB(rport
,(BYTE
*)muiimage
[SIM_PREFS
],left
+(width
/2),top
+(height
/2),IntuitionBase
);
687 //UWORD *pens = data->dri->dri_Pens;
689 int_RenderWindowFrame(data
->window
,left
,top
,width
,height
,data
->dri
,IntuitionBase
);
691 if (!(data
->flags
& SYSIFLG_NOBORDER
))
695 int_RenderWindowFrameBorder(data
->window
,left
,top
,width
,height
,data
->dri
,IntuitionBase
);
699 renderimageframe(rport
, data
->type
, msg
->imp_State
, data
->dri
->dri_Pens
,
700 left
, top
, width
, height
, IntuitionBase
);
712 if (data
->type
== SNAPSHOTIMAGE
)
714 if (msg
->imp_State
== IDS_SELECTED
)
716 DrawIB(rport
,(BYTE
*)muiimage
[SIM_SNAPSHOTSEL
],left
+(width
/2),top
+(height
/2),IntuitionBase
);
720 DrawIB(rport
,(BYTE
*)muiimage
[SIM_SNAPSHOT
],left
+(width
/2),top
+(height
/2),IntuitionBase
);
724 if (data
->type
== POPUPIMAGE
)
726 if (msg
->imp_State
== IDS_SELECTED
)
728 DrawIB(rport
,(BYTE
*)muiimage
[SIM_POPUPSEL
],left
+(width
/2),top
+(height
/2),IntuitionBase
);
732 DrawIB(rport
,(BYTE
*)muiimage
[SIM_POPUP
],left
+(width
/2),top
+(height
/2),IntuitionBase
);
736 if (data
->type
== ICONIFYIMAGE
)
738 if (msg
->imp_State
== IDS_SELECTED
)
740 DrawIB(rport
,(BYTE
*)muiimage
[SIM_ICONIFYSEL
],left
+(width
/2),top
+(height
/2),IntuitionBase
);
744 DrawIB(rport
,(BYTE
*)muiimage
[SIM_ICONIFY
],left
+(width
/2),top
+(height
/2),IntuitionBase
);
748 if (data
->type
== LOCKIMAGE
)
750 if ((msg
->imp_State
== IDS_SELECTED
) || (msg
->imp_State
== IDS_INACTIVESELECTED
))
752 DrawIB(rport
,(BYTE
*)muiimage
[SIM_LOCKSEL
],left
+(width
/2),top
+(height
/2),IntuitionBase
);
756 DrawIB(rport
,(BYTE
*)muiimage
[SIM_LOCK
],left
+(width
/2),top
+(height
/2),IntuitionBase
);
765 //UWORD *pens = data->dri->dri_Pens;
767 int_RenderWindowFrame(data
->window
,left
,top
,width
,height
,data
->dri
,IntuitionBase
);
769 if (!(data
->flags
& SYSIFLG_NOBORDER
))
773 int_RenderWindowFrameBorder(data
->window
,left
,top
,width
,height
,data
->dri
,IntuitionBase
);
777 renderimageframe(rport
, data
->type
, msg
->imp_State
, data
->dri
->dri_Pens
,
778 left
, top
, width
, height
, IntuitionBase
);
790 DrawJUMP(rport
,msg
->imp_State
,left
+(width
/2),top
+(height
/2),IntuitionBase
);
795 } /* switch (image type) */
796 int_FreeCustomPrefs(TYPE_SYSICLASS
,data
->dri
,IntuitionBase
);
800 /**************************************************************************************************/
802 AROS_UFH3S(IPTR
, dispatch_sysiclass
,
803 AROS_UFHA(Class
*, cl
, A0
),
804 AROS_UFHA(Object
*, obj
, A2
),
805 AROS_UFHA(Msg
, msg
, A1
)
811 struct SysIData
*data
;
813 D(bug(dprintf("dispatch_sysiclass: class 0x%lx object 0x%lx\n",cl
,obj
);))
815 switch (msg
->MethodID
)
819 D(bug(dprintf("dispatch_sysiclass: OM_NEW\n");))
821 retval
= (IPTR
)sysi_new(cl
, (Class
*)obj
, (struct opSet
*)msg
);
825 D(bug(dprintf("dispatch_sysiclass: OM_DISPOSE\n");))
827 data
= INST_DATA(cl
, obj
);
828 DisposeObject(data
->frame
);
829 retval
= DoSuperMethodA(cl
, obj
, msg
);
834 D(bug(dprintf("dispatch_sysiclass: OM_SET\n");))
836 data
= INST_DATA(cl
, obj
);
838 DoMethodA((Object
*)data
->frame
, msg
);
839 retval
= DoSuperMethodA(cl
, obj
, msg
);
844 D(bug(dprintf("dispatch_sysiclass: IM_DRAW\n");))
846 sysi_draw(cl
, obj
, (struct impDraw
*)msg
);
850 retval
= DoSuperMethodA(cl
, obj
, msg
);
854 D(bug(dprintf("dispatch_sysiclass: done\n");))
861 /**************************************************************************************************/
865 /**************************************************************************************************/
867 /* Initialize our class. */
868 struct IClass
*InitSysIClass (struct IntuitionBase
* IntuitionBase
)
870 struct IClass
*cl
= NULL
;
872 cl
= MakeClass(SYSICLASS
, IMAGECLASS
, NULL
, sizeof(struct SysIData
), 0);
876 cl
->cl_Dispatcher
.h_Entry
= (APTR
)AROS_ASMSYMNAME(dispatch_sysiclass
);
877 cl
->cl_Dispatcher
.h_SubEntry
= NULL
;
878 cl
->cl_UserData
= (IPTR
)IntuitionBase
;
885 /**************************************************************************************************/
888 static UWORD
getbgpen(ULONG state
, UWORD
*pens
)
900 case IDS_INACTIVENORMAL
:
901 bg
= pens
[BACKGROUNDPEN
];
904 bg
= pens
[BACKGROUNDPEN
];
911 /**************************************************************************************************/
913 void renderimageframe(struct RastPort
*rp
, ULONG which
, ULONG state
, UWORD
*pens
,
914 WORD left
, WORD top
, WORD width
, WORD height
,
915 struct IntuitionBase
*IntuitionBase
)
917 WORD right
= left
+ width
- 1;
918 WORD bottom
= top
+ height
- 1;
919 BOOL leftedgegodown
= FALSE
;
920 BOOL topedgegoright
= FALSE
;
925 /* draw separator line at the right side */
926 SetAPen(rp
, pens
[SHINEPEN
]);
927 RectFill(rp
, right
, top
, right
, bottom
- 1);
928 SetAPen(rp
, pens
[SHADOWPEN
]);
929 WritePixel(rp
, right
, bottom
);
937 /* draw separator line at the left side */
938 SetAPen(rp
, pens
[SHINEPEN
]);
939 WritePixel(rp
, left
, top
);
940 SetAPen(rp
, pens
[SHADOWPEN
]);
941 RectFill(rp
, left
, top
+ 1, left
, bottom
);
948 leftedgegodown
= TRUE
;
953 topedgegoright
= TRUE
;
957 if (left
== 0) leftedgegodown
= TRUE
;
958 if (top
== 0) topedgegoright
= TRUE
;
960 SetAPen(rp
, pens
[((state
== IDS_SELECTED
) || (state
== IDS_INACTIVESELECTED
)) ? SHADOWPEN
: SHINEPEN
]);
966 bottom
- (leftedgegodown
? 0 : 1));
969 RectFill(rp
, left
+ 1,
971 right
- (topedgegoright
? 0 : 1),
974 SetAPen(rp
, pens
[((state
== IDS_SELECTED
) || (state
== IDS_INACTIVESELECTED
)) ? SHINEPEN
: SHADOWPEN
]);
978 top
+ (topedgegoright
? 1 : 0),
983 RectFill(rp
, left
+ (leftedgegodown
? 1 : 0),
989 /**************************************************************************************************/