7 * (C) Copyright 1998 Manuel Lemos.
8 * (C) Copyright 1996-1997 Ian J. Einman.
9 * (C) Copyright 1993-1996 Jaba Development.
10 * (C) Copyright 1993-1996 Jan van den Baard.
11 * All Rights Reserved.
14 * Revision 42.4 2004/06/16 20:16:48 verhaegs
15 * Use METHODPROTO, METHOD_END and REGFUNCPROTOn where needed.
17 * Revision 42.3 2000/08/17 15:09:18 chodorowski
18 * Fixed compiler warnings.
20 * Revision 42.2 2000/05/15 19:27:01 stegerg
21 * another hundreds of REG() macro replacements in func headers/protos.
23 * Revision 42.1 2000/05/14 23:32:47 stegerg
24 * changed over 200 function headers which all use register
25 * parameters (oh boy ...), because the simple REG() macro
26 * doesn't work with AROS. And there are still hundreds
27 * of headers left to be fixed :(
29 * Many of these functions would also work with stack
30 * params, but since i have fixed every single one
31 * I encountered up to now, I guess will have to do
32 * the same for the rest.
34 * Revision 42.0 2000/05/09 22:09:01 mlemos
35 * Bumped to revision 42.0 before handing BGUI to AROS team
37 * Revision 41.11 2000/05/09 19:54:17 mlemos
38 * Merged with the branch Manuel_Lemos_fixes.
40 * Revision 41.10.2.7 1999/07/04 05:24:40 mlemos
41 * Fixed attempts to render areas witrh invalid dimensions.
43 * Revision 41.10.2.6 1999/07/03 15:17:37 mlemos
44 * Replaced the calls to CallHookPkt to BGUI_CallHookPkt.
46 * Revision 41.10.2.5 1999/07/03 15:12:26 mlemos
47 * Ensured that frame is only drawn if dimensions are bigger than 0.
48 * Removed debug code to warn when dimensions are too small.
50 * Revision 41.10.2.4 1999/07/03 14:29:56 mlemos
51 * Added assertion code to warn frame dimensions are too small.
53 * Revision 41.10.2.3 1999/07/03 14:13:08 mlemos
54 * Fixed off by one mistake on the computation of the minimum frame size
56 * Revision 41.10.2.2 1998/12/07 03:06:59 mlemos
57 * Replaced OpenFont and CloseFont calls by the respective BGUI debug macros.
59 * Revision 41.10.2.1 1998/02/28 02:22:54 mlemos
60 * Made setting the frame title to NULL to reset text title object.
62 * Revision 41.10 1998/02/25 21:12:05 mlemos
65 * Revision 1.1 1998/02/25 17:08:20 mlemos
71 /// Class definitions.
73 #include "include/classdefs.h"
76 * Object instance data.
79 ULONG fd_Flags
; /* Flags. */
80 Object
*fd_Title
; /* Frame title. */
81 struct TextAttr
*fd_TitleFont
; /* Font for the title. */
82 struct TextFont
*fd_Font
; /* The opened font. */
83 struct Hook fd_DefBackfill
; /* Default backfill hook. */
84 struct Hook
*fd_FrameHook
; /* Custom frame hook. */
85 struct Hook
*fd_BackFillHook
; /* Custom backfill hook. */
86 struct bguiPattern
*fd_Pattern
; /* Normal fill pattern. */
87 struct bguiPattern
*fd_SelPattern
; /* Selected fill pattern. */
88 Object
*fd_ParentGroup
; /* Parent Group. */
89 UWORD fd_Type
; /* Frame type. */
90 UWORD fd_BackFill
; /* Backfilling type. */
91 UBYTE fd_Horizontal
; /* Horizontal thickness */
92 UBYTE fd_Vertical
; /* Vertical thickness */
94 UWORD fd_BackPen
, fd_BackPen2
; /* Normal backfill pens. */
95 UWORD fd_SelPen
, fd_SelPen2
; /* Selected backfill pens. */
96 BYTE fd_OuterX1
, fd_OuterX2
, fd_OuterY1
, fd_OuterY2
;
97 BYTE fd_InnerX1
, fd_InnerX2
, fd_InnerY1
, fd_InnerY2
;
100 #define FRF_SELFOPEN (1<<31)
101 #define FRF_INBORDER (1<<30) /* Image in window border? */
102 #define FRF_BACKDRI (1<<29)
103 #define FRF_SELDRI (1<<28)
104 #define FRF_BACKDRI2 (1<<27)
105 #define FRF_SELDRI2 (1<<26)
106 #define FRF_CUST_THICK (1<<25)
107 #define FRF_FILL_OUTER (1<<24)
109 #define FD_ENTRY(tag, offset, flags) PACK_ENTRY(FRM_TAGSTART, tag, fd_, offset, flags)
110 #define FD_FLAG(tag, flag) PACK_LONGBIT(FRM_TAGSTART, tag, fd_, fd_Flags, PKCTRL_BIT, flag)
112 static ULONG FramePackTable
[] =
114 PACK_STARTTABLE(FRM_TAGSTART
),
116 FD_ENTRY(FRM_Flags
, fd_Flags
, PKCTRL_ULONG
),
117 FD_ENTRY(FRM_CustomHook
, fd_FrameHook
, PKCTRL_ULONG
),
118 FD_ENTRY(FRM_BackFillHook
, fd_BackFillHook
, PKCTRL_ULONG
),
119 FD_ENTRY(FRM_TextAttr
, fd_TitleFont
, PKCTRL_ULONG
),
120 FD_ENTRY(FRM_Type
, fd_Type
, PKCTRL_UWORD
),
121 FD_ENTRY(FRM_BackFill
, fd_BackFill
, PKCTRL_UWORD
),
122 FD_ENTRY(FRM_FillPattern
, fd_Pattern
, PKCTRL_ULONG
),
123 FD_ENTRY(FRM_SelectedFillPattern
, fd_SelPattern
, PKCTRL_ULONG
),
125 FD_ENTRY(FRM_FrameWidth
, fd_Horizontal
, PKCTRL_UBYTE
),
126 FD_ENTRY(FRM_FrameHeight
, fd_Vertical
, PKCTRL_UBYTE
),
127 FD_ENTRY(FRM_OuterOffsetLeft
, fd_OuterX1
, PKCTRL_BYTE
),
128 FD_ENTRY(FRM_OuterOffsetRight
, fd_OuterX2
, PKCTRL_BYTE
),
129 FD_ENTRY(FRM_OuterOffsetTop
, fd_OuterY1
, PKCTRL_BYTE
),
130 FD_ENTRY(FRM_OuterOffsetBottom
, fd_OuterY2
, PKCTRL_BYTE
),
131 FD_ENTRY(FRM_InnerOffsetLeft
, fd_InnerX1
, PKCTRL_BYTE
),
132 FD_ENTRY(FRM_InnerOffsetRight
, fd_InnerX2
, PKCTRL_BYTE
),
133 FD_ENTRY(FRM_InnerOffsetTop
, fd_InnerY1
, PKCTRL_BYTE
),
134 FD_ENTRY(FRM_InnerOffsetBottom
, fd_InnerY2
, PKCTRL_BYTE
),
136 FD_FLAG(FRM_EdgesOnly
, FRF_EDGES_ONLY
),
137 FD_FLAG(FRM_Recessed
, FRF_RECESSED
),
138 FD_FLAG(FRM_CenterTitle
, FRF_CENTER_TITLE
),
139 FD_FLAG(FRM_HighlightTitle
, FRF_HIGHLIGHT_TITLE
),
140 FD_FLAG(FRM_ThinFrame
, FRF_THIN_FRAME
),
141 FD_FLAG(FRM_TitleLeft
, FRF_TITLE_LEFT
),
142 FD_FLAG(FRM_TitleRight
, FRF_TITLE_RIGHT
),
149 * Built-in background hook. This hook will take
150 * care of the backfilling rasters and the special
153 //STATIC SAVEDS ASM BuiltInBack(REG(a0) struct Hook *hook, REG(a2) Object *obj, REG(a1) struct FrameDrawMsg *fdm)
154 STATIC SAVEDS ASM
REGFUNC3(IPTR
, BuiltInBack
,
155 REGPARAM(A0
, struct Hook
*, hook
),
156 REGPARAM(A2
, Object
*, obj
),
157 REGPARAM(A1
, struct FrameDrawMsg
*, fdm
))
159 FD
*fd
= INST_DATA(OCLASS(obj
), obj
);
160 UWORD
*pens
= PENS(fdm
->fdm_DrawInfo
), apen
, bpen
;
161 struct RastPort
*rp
= fdm
->fdm_RPort
;
163 struct bguiPattern
*pat
;
167 int x1
= fdm
->fdm_Bounds
->MinX
;
168 int x2
= fdm
->fdm_Bounds
->MaxX
;
169 int y1
= fdm
->fdm_Bounds
->MinY
;
170 int y2
= fdm
->fdm_Bounds
->MaxY
;
172 BOOL sel
= ((fdm
->fdm_State
== IDS_SELECTED
) || (fdm
->fdm_State
== IDS_INACTIVESELECTED
));
174 STATIC UBYTE backfill
[][2] =
176 { BACKGROUNDPEN
, BACKGROUNDPEN
}, // STANDARD_FILL
177 { SHINEPEN
, BACKGROUNDPEN
}, // SHINE_RASTER
178 { SHADOWPEN
, BACKGROUNDPEN
}, // SHADOW_RASTER
179 { SHINEPEN
, SHADOWPEN
}, // SHINE_SHADOW_RASTER
180 { FILLPEN
, BACKGROUNDPEN
}, // FILL_RASTER
181 { SHINEPEN
, FILLPEN
}, // SHINE_FILL_RASTER
182 { SHADOWPEN
, FILLPEN
}, // SHADOW_FILL_RASTER
183 { SHINEPEN
, SHINEPEN
}, // SHINE_BLOCK
184 { SHADOWPEN
, SHADOWPEN
}, // SHADOW_BLOCK
185 { FILLPEN
, FILLPEN
}, // FILL_BLOCK
189 * Render the backfill?
191 if (fdm
->fdm_MethodID
== FRM_RENDER
)
198 ib
.Width
= x2
- x1
+ 1;
199 ib
.Height
= y2
- y1
+ 1;
201 pat
= fd
->fd_Pattern
;
202 if (sel
&& !pat
) pat
= fd
->fd_SelPattern
;
206 BGUI_FillRectPattern(rp
, pat
, x1
, y1
, x2
, y2
);
210 if (fd
->fd_BackFill
== STANDARD_FILL
)
213 * A raster backfill. Set up the pens.
217 * First check for a normal (dri)pen.
218 * If none is given we use the default color.
220 if ((apen
= fd
->fd_BackPen
) != (UWORD
)~0)
222 if (fd
->fd_Flags
& FRF_BACKDRI
) apen
= pens
[apen
];
224 if ((bpen
= fd
->fd_BackPen2
) == (UWORD
)~0)
230 if (fd
->fd_Flags
& FRF_SELDRI2
) bpen
= pens
[bpen
];
234 if (sel
&& (fd
->fd_SelPen
!= (UWORD
)~0))
237 * First check for a selected (dri)pen.
238 * If none is given we use the default color.
240 if ((apen
= fd
->fd_SelPen
) != (UWORD
)~0)
242 if (fd
->fd_Flags
& FRF_SELDRI
) apen
= pens
[apen
];
244 if ((bpen
= fd
->fd_SelPen2
) == (UWORD
)~0)
250 if (fd
->fd_Flags
& FRF_SELDRI2
) bpen
= pens
[bpen
];
255 if (apen
== (UWORD
)~0)
260 * NeXT, DropBox and Ridge frames do not support a SELECTED state
261 * so we force the BACKGROUNDPEN for these types.
266 case FRTYPE_FUZZ_RIDGE
:
267 case FRTYPE_RADIOBUTTON
:
268 apen
= BACKGROUNDPEN
;
273 * Check the state of the frame
275 switch (fdm
->fdm_State
)
280 case IDS_INACTIVESELECTED
:
281 case IDS_INACTIVENORMAL
:
282 apen
= BACKGROUNDPEN
;
286 * And BACKGROUNDPEN for normal frames.
288 apen
= ((fd
->fd_Flags
& FRF_INBORDER
) || (fd
->fd_Type
== FRTYPE_BORDER
)) ? FILLPEN
: BACKGROUNDPEN
;
292 apen
= bpen
= pens
[apen
];
297 fill
= fd
->fd_BackFill
;
298 if (fill
> FILL_BLOCK
) fill
= 0;
300 apen
= pens
[backfill
[fill
][0]];
301 bpen
= pens
[backfill
[fill
][1]];
307 RenderBackFillRaster(rp
, &ib
, apen
, bpen
);
317 * Frame background routine.
319 METHOD(FrameClassBackfill
, struct fmBackfill
*, fmb
)
321 FD
*fd
= INST_DATA(cl
, obj
);
322 struct FrameDrawMsg fdraw
;
325 * Setup framedraw message.
327 fdraw
.fdm_MethodID
= FRM_RENDER
;
328 fdraw
.fdm_RPort
= fmb
->fmb_BInfo
->bi_RPort
;
329 fdraw
.fdm_DrawInfo
= fmb
->fmb_BInfo
->bi_DrInfo
;
330 fdraw
.fdm_Bounds
= fmb
->fmb_Bounds
;
331 fdraw
.fdm_State
= fmb
->fmb_State
;
334 * Call the custom back-fill hook routine.
335 * Note that this can also be the default backfill hook
336 * which is defined above.
338 BGUI_CallHookPkt(fd
->fd_BackFillHook
, (VOID
*)obj
, (VOID
*)&fdraw
);
344 #define Line(x1,y1,x2,y2) { Move(rp, x1, y1); Draw(rp, x2, y2); }
345 #define Point(x1,y1) WritePixel(rp, x1, y1)
349 * Render the radio button frame
351 STATIC VOID
RenderRadioFrame(struct bmRender
*bmr
, WORD l
, WORD t
, WORD r
, WORD b
, FD
*fd
)
353 struct BaseInfo
*bi
= bmr
->bmr_BInfo
;
354 struct RastPort
*rp
= bi
->bi_RPort
;
356 BOOL normal
= !(fd
->fd_Flags
& FRF_RECESSED
);
357 BOOL thin
= fd
->fd_Flags
& FRF_THIN_FRAME
;
360 * Check if we need to draw a normal or a selected frame
362 switch (bmr
->bmr_Flags
)
365 case IDS_INACTIVESELECTED
:
371 * Draw the shine side of the frame
375 *a
++ = l
+ 2; *a
++ = t
;
376 *a
++ = l
; *a
++ = t
+ 2;
377 *a
++ = l
; *a
++ = b
- 2;
378 *a
++ = l
+ 2; *a
++ = b
;
379 *a
++ = l
+ 2; *a
++ = b
- 1;
386 *a
++ = l
+ 1; *a
++ = b
- 2;
387 *a
++ = l
+ 1; *a
++ = t
+ 2;
388 *a
++ = l
+ 2; *a
++ = t
+ 1;
391 BSetDPenA(bi
, normal
? SHINEPEN
: SHADOWPEN
);
393 PolyDraw(rp
, (a
- array
) >> 1, array
);
396 * Draw the shadow side of the frame
400 *a
++ = r
- 2; *a
++ = b
;
401 *a
++ = r
; *a
++ = b
- 2;
402 *a
++ = r
; *a
++ = t
+ 2;
403 *a
++ = r
- 2; *a
++ = t
;
404 *a
++ = r
- 2; *a
++ = t
+ 1;
411 *a
++ = r
- 1; *a
++ = t
+ 2;
412 *a
++ = r
- 1; *a
++ = b
- 2;
413 *a
++ = r
- 2; *a
++ = b
- 1;
416 BSetDPenA(bi
, normal
? SHADOWPEN
: SHINEPEN
);
418 PolyDraw(rp
, (a
- array
) >> 1, array
);
423 * Render the tab frame.
425 STATIC VOID
RenderTabFrame(struct bmRender
*bmr
, int l0
, int t0
, int r0
, int b0
, FD
*fd
)
427 struct BaseInfo
*bi
= bmr
->bmr_BInfo
;
428 struct RastPort
*rp
= bi
->bi_RPort
;
430 int l1
= l0
+ 1, l2
= l0
+ 2, l3
= l0
+ 3, l4
= l0
+ 4;
431 int r1
= r0
- 1, r2
= r0
- 2, r3
= r0
- 3, r4
= r0
- 4;
432 int t1
= t0
+ 1, t2
= t0
+ 2, t3
= t0
+ 3, t4
= t0
+ 4;
433 int b1
= b0
- 1, b2
= b0
- 2, b3
= b0
- 3, b4
= b0
- 4;
435 BOOL sel
= ((bmr
->bmr_Flags
== IDS_SELECTED
) || (bmr
->bmr_Flags
== IDS_INACTIVESELECTED
));
436 BOOL thin
= fd
->fd_Flags
& FRF_THIN_FRAME
;
444 BSetDPenA(bi
, SHINEPEN
);
448 Line(l1
, t2
, l1
, b1
); if (!thin
) Line(l2
, t2
, l2
, b1
);
449 Line(l2
, t1
, l3
, t1
);
450 Line(l3
, t0
, r3
, t0
);
454 Line(l0
, b0
, r0
, b0
);
455 Line(l2
, t3
, l2
, b1
); if (!thin
) Line(l3
, t3
, l3
, b1
);
456 Line(l3
, t2
, l4
, t2
);
457 Line(l4
, t1
, r4
, t1
);
463 BSetDPenA(bi
, SHADOWPEN
);
466 Line(r2
, t1
, r3
, t1
);
467 Line(r1
, t2
, r1
, b1
); if (!thin
) Line(r2
, t2
, r2
, b1
);
472 Line(r3
, t2
, r4
, t2
);
473 Line(r2
, t3
, r2
, b1
); if (!thin
) Line(r3
, t3
, r3
, b1
);
477 case FRTYPE_TAB_BOTTOM
:
481 BSetDPenA(bi
, SHINEPEN
);
485 Line(l1
, t1
, l1
, b2
); if (!thin
) Line(l2
, t1
, l2
, b2
);
486 Line(l2
, b1
, l3
, b1
);
490 Line(l2
, t1
, l2
, b3
); if (!thin
) Line(l3
, t1
, l3
, b3
);
491 Line(l3
, b2
, l4
, b2
);
497 BSetDPenA(bi
, SHADOWPEN
);
501 Line(r3
, b1
, r2
, b1
);
502 Line(r1
, t1
, r1
, b2
); if (!thin
) Line(r2
, t1
, r2
, b2
);
503 Line(l3
, b0
, r3
, b0
);
507 Line(l0
, t0
, r0
, t0
);
508 Line(r4
, b2
, r3
, b2
);
509 Line(r2
, t1
, r2
, b3
); if (!thin
) Line(r3
, t1
, r3
, b3
);
510 Line(l4
, b1
, r4
, b1
);
518 * Render the XEN button frame.
520 STATIC VOID
RenderXenFrame(struct bmRender
*bmr
, WORD l
, WORD t
, WORD r
, WORD b
, FD
*fd
)
522 struct BaseInfo
*bi
= bmr
->bmr_BInfo
;
523 struct RastPort
*rp
= bi
->bi_RPort
;
526 * Setup pen for the XEN lines
527 * around the normal button frame.
529 BSetDPenA(bi
, SHADOWPEN
);
537 HLine(rp
, l
, t
- 1, r
);
538 VLine(rp
, r
- 1, t
, b
);
539 HLine(rp
, l
, b
- 1, r
);
540 VLine(rp
, l
- 1, t
, b
);
545 RenderBevelBox(bi
, l
, t
, r
, b
, bmr
->bmr_Flags
, fd
->fd_Flags
& FRF_RECESSED
, fd
->fd_Flags
& FRF_THIN_FRAME
);
550 * Pass on the frame thickness.
552 //STATIC ASM VOID FrameThickness(REG(a0) Class *cl, REG(a2) Object *obj)
553 STATIC ASM
REGFUNC2(VOID
, FrameThickness
,
554 REGPARAM(A0
, Class
*, cl
),
555 REGPARAM(A2
, Object
*, obj
))
557 FD
*fd
= INST_DATA(cl
, obj
);
558 struct ThicknessMsg tm
;
563 STATIC UBYTE thick
[][4] =
565 { 1, 1, 1, 1 }, // FRTYPE_CUSTOM
566 { 2, 1, 1, 1 }, // FRTYPE_BUTTON
567 { 4, 2, 2, 2 }, // FRTYPE_RIDGE
568 { 6, 3, 3, 3 }, // FRTYPE_DROPBOX
569 { 4, 2, 2, 2 }, // FRTYPE_NEXT
570 { 1, 1, 1, 1 }, // FRTYPE_RADIOBUTTON
571 { 3, 2, 2, 2 }, // FRTYPE_XEN_BUTTON
572 { 2, 1, 1, 1 }, // FRTYPE_TAB_ABOVE
573 { 2, 1, 1, 1 }, // FRTYPE_TAB_BELOW
574 { 1, 1, 1, 1 }, // FRTYPE_BORDER
575 { 0, 0, 0, 0 }, // FRTYPE_NONE
576 { 3, 2, 3, 3 }, // FRTYPE_FUZZ_BUTTON
577 { 3, 2, 3, 3 }, // FRTYPE_FUZZ_RIDGE
578 { 6, 2, 5, 2 }, // FRTYPE_TAB_TOP
579 { 6, 2, 5, 2 }, // FRTYPE_TAB_BOTTOM
580 { 2, 6, 2, 5 }, // FRTYPE_TAB_LEFT
581 { 2, 6, 2, 5 }, // FRTYPE_TAB_RIGHT
584 if (!(fd
->fd_Flags
& FRF_CUST_THICK
))
586 thin
= fd
->fd_Flags
& FRF_THIN_FRAME
;
591 if (fd
->fd_FrameHook
)
594 * Yes. Call it to get the thickness
595 * of the custom frame.
597 tm
.tm_MethodID
= FRM_THICKNESS
;
598 tm
.tm_Thickness
.Horizontal
= &h
;
599 tm
.tm_Thickness
.Vertical
= &v
;
603 * If this method is not understood
604 * by the hook we use default values.
606 if (BGUI_CallHookPkt(fd
->fd_FrameHook
, (VOID
*)obj
, (VOID
*)&tm
) != FRC_OK
)
614 * Setup frame thickness of the internal frames.
617 if (type
> FRTYPE_FUZZ_RIDGE
) type
= 0;
619 h
= thick
[type
][thin
? 2 : 0];
620 v
= thick
[type
][thin
? 3 : 1];
622 fd
->fd_Horizontal
= h
;
629 * Setup frame attributes.
631 //STATIC ASM VOID SetFrameAttrs(REG(a0) Class *cl, REG(a2) Object *obj, REG(a1) struct TagItem *attr)
632 STATIC ASM
REGFUNC3(VOID
, SetFrameAttrs
,
633 REGPARAM(A0
, Class
*, cl
),
634 REGPARAM(A2
, Object
*, obj
),
635 REGPARAM(A1
, struct TagItem
*, attr
))
637 FD
*fd
= INST_DATA(cl
, obj
);
639 struct TagItem
*tstate
= attr
, *tag
;
644 if (tag
= FindTagItem(FRM_Template
, attr
))
646 ob
= (Object
*)tag
->ti_Data
;
649 Get_Attr(ob
, FRM_Template
, &temp
);
652 CopyMem((FD
*)temp
, fd
, sizeof(FD
));
653 fd
->fd_Flags
&= ~FRF_SELFOPEN
;
658 BGUI_PackStructureTags((APTR
)fd
, FramePackTable
, attr
);
663 while (tag
= NextTagItem(&tstate
))
670 fd
->fd_ParentGroup
= (Object
*)data
;
674 case FRM_FrameHeight
:
675 fd
->fd_Flags
|= FRF_CUST_THICK
;
679 if (fd
->fd_Font
&& (fd
->fd_Flags
& FRF_SELFOPEN
))
680 BGUI_CloseFont(fd
->fd_Font
);
681 fd
->fd_Font
= (struct TextFont
*)data
;
682 fd
->fd_Flags
&= ~FRF_SELFOPEN
;
688 if (tf
= BGUI_OpenFont((struct TextAttr
*)tag
->ti_Data
))
690 if (fd
->fd_Font
&& (fd
->fd_Flags
& FRF_SELFOPEN
))
691 BGUI_CloseFont(fd
->fd_Font
);
693 fd
->fd_TitleFont
= (struct TextAttr
*)tag
->ti_Data
;
694 fd
->fd_Flags
|= FRF_SELFOPEN
;
700 fd
->fd_BackFill
= data
;
701 fd
->fd_BackFillHook
= NULL
;
702 fd
->fd_Flags
&= ~FRF_EDGES_ONLY
;
705 case FRM_BackRasterPen
:
706 fd
->fd_BackPen2
= data
;
707 fd
->fd_Flags
&= ~FRF_BACKDRI2
;
708 if (fd
->fd_BackPen
!= (UWORD
)~0) break;
710 fd
->fd_BackPen
= data
;
711 fd
->fd_Flags
&= ~FRF_BACKDRI
;
714 case FRM_BackRasterDriPen
:
715 fd
->fd_BackPen2
= data
;
716 fd
->fd_Flags
|= FRF_BACKDRI2
;
717 if (fd
->fd_BackPen
!= (UWORD
)~0) break;
719 fd
->fd_BackPen
= data
;
720 fd
->fd_Flags
|= FRF_BACKDRI
;
723 case FRM_SelectedBackRasterPen
:
724 fd
->fd_SelPen2
= data
;
725 fd
->fd_Flags
&= ~FRF_SELDRI2
;
726 if (fd
->fd_SelPen
!= (UWORD
)~0) break;
727 case FRM_SelectedBackPen
:
728 fd
->fd_SelPen
= data
;
729 fd
->fd_Flags
&= ~FRF_SELDRI
;
732 case FRM_SelectedBackRasterDriPen
:
733 fd
->fd_SelPen2
= data
;
734 fd
->fd_Flags
|= FRF_SELDRI2
;
735 if (fd
->fd_SelPen
!= (UWORD
)~0) break;
736 case FRM_SelectedBackDriPen
:
737 fd
->fd_SelPen
= data
;
738 fd
->fd_Flags
|= FRF_SELDRI
;
742 if (!fd
->fd_Title
&& data
)
743 fd
->fd_Title
= BGUI_NewObject(BGUI_TEXT_GRAPHIC
, TEXTA_CopyText
, TRUE
, TAG_DONE
);
747 DoSetMethodNG(fd
->fd_Title
, TEXTA_Text
, data
, TAG_DONE
);
750 DisposeObject(fd
->fd_Title
);
757 if (!fd
->fd_Title
) fd
->fd_Title
= BGUI_NewObject(BGUI_TEXT_GRAPHIC
, TEXTA_CopyText
, TRUE
, TAG_DONE
);
758 if (fd
->fd_Title
) DoSetMethodNG(fd
->fd_Title
, TEXTA_TextID
, data
, TAG_DONE
);
765 if (data
) fd
->fd_Flags
|= FRF_INBORDER
;
766 else fd
->fd_Flags
&= ~FRF_INBORDER
;
772 FrameThickness(cl
, obj
);
780 if (fd
->fd_FrameHook
) fd
->fd_Type
= FRTYPE_CUSTOM
;
781 else if (!fd
->fd_Type
) fd
->fd_Type
= FRTYPE_BUTTON
;
783 if (fd
->fd_BackFillHook
== NULL
)
784 fd
->fd_BackFillHook
= &fd
->fd_DefBackfill
;
789 case FRTYPE_TAB_BOTTOM
:
790 case FRTYPE_TAB_LEFT
:
791 case FRTYPE_TAB_RIGHT
:
792 fd
->fd_Flags
|= FRF_FILL_OUTER
;
795 fd
->fd_Flags
&= ~FRF_FILL_OUTER
;
803 * Create a shiny new object.
805 METHOD(FrameClassNew
, struct opSet
*, ops
)
811 * First we let the superclass
812 * create a new object.
814 if (rc
= AsmDoSuperMethodA(cl
, obj
, (Msg
)ops
))
817 * Get us the instance data.
819 fd
= INST_DATA(cl
, rc
);
824 fd
->fd_Type
= FRTYPE_BUTTON
;
825 fd
->fd_BackPen
= (UWORD
)~0;
826 fd
->fd_SelPen
= (UWORD
)~0;
827 fd
->fd_BackPen2
= (UWORD
)~0;
828 fd
->fd_SelPen2
= (UWORD
)~0;
830 fd
->fd_DefBackfill
.h_Entry
= (HOOKFUNC
)BuiltInBack
;
835 SetFrameAttrs(cl
, (Object
*)rc
, ops
->ops_AttrList
);
836 FrameThickness(cl
, (Object
*)rc
);
845 * Change one or more attrubutes.
847 METHOD(FrameClassSet
, struct opSet
*, ops
)
849 FD
*fd
= INST_DATA(cl
, obj
);
853 * First we let the superclass
854 * change the attributes it
857 rc
= AsmDoSuperMethodA(cl
, obj
, (Msg
)ops
);
862 SetFrameAttrs(cl
, obj
, ops
->ops_AttrList
);
870 * Give an attribute value.
872 METHOD(FrameClassGet
, struct opGet
*, opg
)
874 FD
*fd
= INST_DATA(cl
, obj
);
875 ULONG rc
= 1, tag
= opg
->opg_AttrID
, *store
= opg
->opg_Storage
;
878 * First we see if the attribute
879 * they want is known to us. If not
880 * we pass it onto the superclass.
889 STORE fd
->fd_Horizontal
;
891 case FRM_FrameHeight
:
892 STORE fd
->fd_Vertical
;
896 STORE fd
->fd_Flags
& FRF_BACKDRI
? ~0 : fd
->fd_BackPen
;
899 STORE fd
->fd_Flags
& FRF_BACKDRI
? fd
->fd_BackPen
: ~0;
901 case FRM_SelectedBackPen
:
902 STORE fd
->fd_Flags
& FRF_SELDRI
? ~0 : fd
->fd_SelPen
;
904 case FRM_SelectedBackDriPen
:
905 STORE fd
->fd_Flags
& FRF_SELDRI
? fd
->fd_SelPen
: ~0;
907 case FRM_BackRasterPen
:
908 STORE fd
->fd_Flags
& FRF_BACKDRI2
? ~0 : fd
->fd_BackPen2
;
910 case FRM_BackRasterDriPen
:
911 STORE fd
->fd_Flags
& FRF_BACKDRI2
? fd
->fd_BackPen2
: ~0;
913 case FRM_SelectedBackRasterPen
:
914 STORE fd
->fd_Flags
& FRF_SELDRI2
? ~0 : fd
->fd_SelPen2
;
916 case FRM_SelectedBackRasterDriPen
:
917 STORE fd
->fd_Flags
& FRF_SELDRI2
? fd
->fd_SelPen2
: ~0;
921 rc
= BGUI_UnpackStructureTag((UBYTE
*)fd
, FramePackTable
, tag
, store
);
922 if (!rc
) rc
= AsmDoSuperMethodA(cl
, obj
, (Msg
)opg
);
931 * Dispose of the object.
933 METHOD(FrameClassDispose
, Msg
, msg
)
935 FD
*fd
= INST_DATA(cl
, obj
);
940 if (fd
->fd_Font
&& (fd
->fd_Flags
& FRF_SELFOPEN
))
941 BGUI_CloseFont(fd
->fd_Font
);
944 * Dispose of the text graphic.
946 if (fd
->fd_Title
) DisposeObject(fd
->fd_Title
);
949 * The rest goes to the superclass.
951 return AsmDoSuperMethodA(cl
, obj
, msg
);
955 /// FRAMEM_SETUPBOUNDS
957 METHOD(FrameClassSetupBounds
, struct fmSetupBounds
*, fmsb
)
959 FD
*fd
= INST_DATA(cl
, obj
);
960 struct IBox
*hb
= fmsb
->fmsb_HitBox
;
961 struct IBox
*ib
= fmsb
->fmsb_InnerBox
;
962 int ox1
= fd
->fd_OuterX1
;
963 int ox2
= fd
->fd_OuterX2
;
964 int oy1
= fd
->fd_OuterY1
;
965 int oy2
= fd
->fd_OuterY2
;
969 hb
->Width
-= ox1
+ ox2
;
970 hb
->Height
-= oy1
+ oy2
;
972 ox1
+= fd
->fd_InnerX1
+ fd
->fd_Horizontal
;
973 ox2
+= fd
->fd_InnerX2
+ fd
->fd_Horizontal
;
974 oy1
+= fd
->fd_InnerY1
+ fd
->fd_Vertical
;
975 oy2
+= fd
->fd_InnerY2
+ fd
->fd_Vertical
;
979 if (fd
->fd_Font
) oy1
+= fd
->fd_Font
->tf_YSize
;
980 else if (fd
->fd_TitleFont
) oy1
+= fd
->fd_TitleFont
->ta_YSize
;
985 ib
->Width
-= ox1
+ ox2
;
986 ib
->Height
-= oy1
+ oy2
;
988 SetImageBounds(obj
, fmsb
->fmsb_HitBox
);
996 METHOD(FrameClassDimensions
, struct bmDimensions
*, bmd
)
998 FD
*fd
= INST_DATA(cl
, obj
);
999 struct bguiExtent
*be
= bmd
->bmd_Extent
;
1000 int ox
= (fd
->fd_Horizontal
<< 1) + fd
->fd_InnerX1
+ fd
->fd_InnerX2
;
1001 int oy
= (fd
->fd_Vertical
<< 1) + fd
->fd_InnerY1
+ fd
->fd_InnerY2
;
1005 if (fd
->fd_Font
) oy
+= fd
->fd_Font
->tf_YSize
;
1006 else if (fd
->fd_TitleFont
) oy
+= fd
->fd_TitleFont
->ta_YSize
;
1009 be
->be_Min
.Width
+= ox
;
1010 be
->be_Min
.Height
+= oy
;
1012 be
->be_Nom
.Width
+= ox
;
1013 be
->be_Nom
.Height
+= oy
;
1023 METHOD(FrameClassRender
, struct bmRender
*, bmr
)
1025 FD
*fd
= INST_DATA(cl
, obj
);
1026 struct BaseInfo
*bi
= bmr
->bmr_BInfo
;
1027 struct RastPort
*rp
= bi
->bi_RPort
;
1028 struct Rectangle rect
;
1029 struct FrameDrawMsg fdraw
;
1030 WORD l
, t
, r
, b
, place
;
1032 int tv
, th
, dv
, dh
, shadow
, shine
, tmp
, tmp2
;
1033 int state
= bmr
->bmr_Flags
;
1034 int i_fuzz
, i_blank
, i_swap
, i_mix
;
1037 static UWORD pat
[] = { 0x5555, 0xAAAA };
1039 static BYTE taboff
[4][4][2] =
1041 { { 3, 2 }, { 3, 2 }, { 2, 1 }, { 0, 0 } },
1042 { { 3, 2 }, { 3, 2 }, { 0, 0 }, { 2, 1 } },
1043 { { 2, 1 }, { 0, 0 }, { 3, 2 }, { 3, 2 } },
1044 { { 0, 0 }, { 2, 1 }, { 3, 2 }, { 3, 2 } },
1050 * Calculate the frame position and dimensions
1052 l
= IMAGE(obj
)->LeftEdge
;
1053 t
= IMAGE(obj
)->TopEdge
;
1054 r
= IMAGE(obj
)->Width
+ l
- 1;
1055 b
= IMAGE(obj
)->Height
+ t
- 1;
1060 * Setup the font if one is present.
1062 if (fd
->fd_Font
) BSetFont(bi
, fd
->fd_Font
);
1065 * Adjust top position if there is a title present.
1067 if (fd
->fd_Flags
& FRF_CENTER_TITLE
)
1068 t
+= (rp
->TxBaseline
- (rp
->TxHeight
>> 1));
1070 t
+= rp
->TxBaseline
;
1078 * First we do the background.
1080 * When this is a FRF_EDGES_ONLY frame we do nothing.
1081 * No hooks are called, and nothing is filled.
1083 if (!(fd
->fd_Flags
& FRF_EDGES_ONLY
))
1085 if (fd
->fd_Flags
& FRF_FILL_OUTER
)
1087 if (fr
= fd
->fd_ParentGroup
? BASE_DATA(fd
->fd_ParentGroup
)->bc_Frame
: NULL
)
1089 AsmDoMethod(fr
, FRAMEM_BACKFILL
, bi
, &rect
, IDS_NORMAL
);
1093 BSetDPenA(bi
, BACKGROUNDPEN
);
1094 BRectFillA(bi
, &rect
);
1096 tmp
= fd
->fd_Type
- FRTYPE_TAB_TOP
;
1097 tmp2
= ((state
== IDS_SELECTED
) || (state
== IDS_SELECTED
)) ? 1 : 0;
1099 rect
.MinX
+= taboff
[tmp
][0][tmp2
];
1100 rect
.MaxX
-= taboff
[tmp
][1][tmp2
];
1101 rect
.MinY
+= taboff
[tmp
][2][tmp2
];
1102 rect
.MaxY
-= taboff
[tmp
][3][tmp2
];
1106 AsmDoMethod(obj
, FRAMEM_BACKFILL
, bi
, &rect
, state
);
1110 * Get frame thickness.
1112 th
= fd
->fd_Horizontal
;
1113 tv
= fd
->fd_Vertical
;
1115 if ((th
<< 1) > (r
- l
+ 1)) th
= (r
- l
+ 1) >> 1;
1116 if ((tv
<< 1) > (b
- t
+ 1)) tv
= (b
- t
+ 1) >> 1;
1119 * Draw the frame (whatever type it is)
1121 state
= bmr
->bmr_Flags
;
1124 * Selected or normal?
1129 case IDS_INACTIVESELECTED
:
1141 * Swap pens if we must
1144 if (fd
->fd_Flags
& FRF_RECESSED
)
1154 switch (fd
->fd_Type
)
1158 * Fill in the data structures for the custom frame hook
1160 fdraw
.fdm_MethodID
= FRM_RENDER
;
1161 fdraw
.fdm_RPort
= rp
;
1162 fdraw
.fdm_DrawInfo
= bi
->bi_DrInfo
;
1163 fdraw
.fdm_Bounds
= &rect
;
1164 fdraw
.fdm_State
= state
;
1165 fdraw
.fdm_Horizontal
= th
;
1166 fdraw
.fdm_Vertical
= tv
;
1168 * Call the hook routine.
1170 rc
= BGUI_CallHookPkt(fd
->fd_FrameHook
, (VOID
*)obj
, (VOID
*)&fdraw
);
1175 case FRTYPE_DROPBOX
:
1176 case FRTYPE_FUZZ_BUTTON
:
1177 case FRTYPE_FUZZ_RIDGE
:
1184 dv
= (tv
+ th
- 1) / th
; if (dv
< 1) dv
= 1;
1185 dh
= (th
+ tv
- 1) / tv
; if (dh
< 1) dh
= 1;
1187 if (fd
->fd_Type
== FRTYPE_FUZZ_BUTTON
)
1190 * 1/4 Normal, 3/4 Raster
1192 i_fuzz
= (tv
/ dv
) / 4;
1194 if (fd
->fd_Type
== FRTYPE_FUZZ_RIDGE
)
1197 * 1/3 Normal, 1/3 Blank, 1/3 Recessed
1201 i_mix
= (tv
/ dv
) / 3 - 1;
1202 i_swap
= (2 * tv
/ dv
) / 3 - 1;
1204 if (fd
->fd_Type
== FRTYPE_DROPBOX
)
1207 * 1/3 Normal, 1/3 Blank, 1/3 Recessed
1211 i_blank
= (tv
/ dv
) / 3 - 1;
1212 i_swap
= (2 * tv
/ dv
) / 3 - 1;
1214 if (fd
->fd_Type
== FRTYPE_NEXT
)
1217 * 1/2 Recessed, 1/2 Normal
1223 i_swap
= (tv
/ dv
) / 2 - 1;
1225 if (fd
->fd_Type
== FRTYPE_RIDGE
)
1228 * 1/2 Normal, 1/2 Recessed
1232 i_swap
= (tv
/ dv
) / 2 - 1;
1236 * Render the bevelbox.
1238 while ((tv
> 0) && (th
> 0))
1240 if (shine
>= 0) BSetDPenA(bi
, shine
);
1243 BRectFill(bi
, l
, t
, l
+ dh
- 1, b
); l
+= dh
;
1244 if (shadow
>= 0) BSetDPenA(bi
, shadow
);
1247 BRectFill(bi
, l
, b
- dv
+ 1, r
, b
); b
-= dv
;
1250 BRectFill(bi
, r
- dh
+ 1, t
, r
, b
); r
-= dh
;
1251 if (shine
>= 0) BSetDPenA(bi
, shine
);
1254 BRectFill(bi
, l
, t
, r
, t
+ dv
- 1); t
+= dv
;
1260 BSetAfPt(bi
, pat
, 1);
1264 shine
= BACKGROUNDPEN
;
1265 shadow
= BACKGROUNDPEN
;
1275 BSetAfPt(bi
, pat
, 1);
1276 BSetDPenA(bi
, shine
);
1277 BSetDPenB(bi
, shadow
);
1278 shine
= shadow
= -1;
1283 BSetDPenA(bi
, shine
);
1284 BRectFill(bi
, l
, t
, r
, t
+ tv
- 1);
1285 BSetDPenA(bi
, shadow
);
1286 BRectFill(bi
, l
, b
- tv
+ 1, r
, b
);
1290 BSetDPenA(bi
, shine
);
1291 BRectFill(bi
, l
, t
, l
+ th
- 1, b
);
1292 BSetDPenA(bi
, shadow
);
1293 BRectFill(bi
, r
- th
+ 1, t
, r
, b
);
1297 case FRTYPE_RADIOBUTTON
:
1298 RenderRadioFrame(bmr
, l
, t
, r
, b
, fd
);
1301 case FRTYPE_XEN_BUTTON
:
1302 RenderXenFrame(bmr
, l
, t
, r
, b
, fd
);
1305 case FRTYPE_TAB_TOP
:
1306 case FRTYPE_TAB_BOTTOM
:
1307 case FRTYPE_TAB_LEFT
:
1308 case FRTYPE_TAB_RIGHT
:
1309 RenderTabFrame(bmr
, l
, t
, r
, b
, fd
);
1312 case FRTYPE_TAB_ABOVE
:
1316 BSetDPenA(bi
, shine
);
1317 BRectFill(bi
, l
, t
, l
+ th
- 1, b
- tv
);
1318 BSetDPenA(bi
, shadow
);
1319 BRectFill(bi
, l
+ 1, b
- tv
+ 1, r
, b
);
1320 BRectFill(bi
, r
- th
+ 1, t
, r
, b
);
1323 case FRTYPE_TAB_BELOW
:
1327 BSetDPenA(bi
, shine
);
1328 BRectFill(bi
, l
, t
, l
+ th
- 1, b
- tv
+ 1);
1329 BRectFill(bi
, l
, t
, r
- th
+ 1, t
+ tv
- 1);
1330 BSetDPenA(bi
, shadow
);
1331 BRectFill(bi
, r
- th
+ 1, t
, r
, b
);
1336 * Render the borderbox.
1338 RenderBevelBox(bi
, l
, t
, r
, b
, state
, fd
->fd_Flags
& FRF_RECESSED
, TRUE
);
1347 * Render frame the title.
1356 if (fd
->fd_Flags
& FRF_TITLE_LEFT
) place
= 1;
1357 else if (fd
->fd_Flags
& FRF_TITLE_RIGHT
) place
= 2;
1362 RenderTitle(fd
->fd_Title
, bi
, l
, t
, r
- l
+ 1,
1363 fd
->fd_Flags
& FRF_HIGHLIGHT_TITLE
, fd
->fd_Flags
& FRF_CENTER_TITLE
, place
);
1373 METHOD(FrameClassLocalize
, struct bmLocalize
*, bml
)
1375 FD
*fd
= INST_DATA(cl
, obj
);
1378 if (fd
->fd_Title
) rc
= AsmDoMethodA(fd
->fd_Title
, (Msg
)bml
);
1384 /// Class initialization.
1387 * Class function table.
1389 STATIC DPFUNC ClassFunc
[] = {
1390 BASE_RENDER
, (FUNCPTR
)FrameClassRender
,
1391 BASE_DIMENSIONS
, (FUNCPTR
)FrameClassDimensions
,
1392 FRAMEM_BACKFILL
, (FUNCPTR
)FrameClassBackfill
,
1393 FRAMEM_SETUPBOUNDS
, (FUNCPTR
)FrameClassSetupBounds
,
1394 OM_SET
, (FUNCPTR
)FrameClassSet
,
1395 OM_GET
, (FUNCPTR
)FrameClassGet
,
1396 OM_NEW
, (FUNCPTR
)FrameClassNew
,
1397 OM_DISPOSE
, (FUNCPTR
)FrameClassDispose
,
1398 BASE_LOCALIZE
, (FUNCPTR
)FrameClassLocalize
,
1403 * Simple class initialization.
1405 makeproto Class
*InitFrameClass(void)
1407 return BGUI_MakeClass(CLASS_SuperClassBGUI
, BGUI_IMAGE_OBJECT
,
1408 CLASS_ObjectSize
, sizeof(FD
),
1409 CLASS_DFTable
, ClassFunc
,