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_Type
, fd_Type
, PKCTRL_UWORD
),
118 FD_ENTRY(FRM_BackFill
, fd_BackFill
, PKCTRL_UWORD
),
120 FD_ENTRY(FRM_FrameWidth
, fd_Horizontal
, PKCTRL_UBYTE
),
121 FD_ENTRY(FRM_FrameHeight
, fd_Vertical
, PKCTRL_UBYTE
),
122 FD_ENTRY(FRM_OuterOffsetLeft
, fd_OuterX1
, PKCTRL_BYTE
),
123 FD_ENTRY(FRM_OuterOffsetRight
, fd_OuterX2
, PKCTRL_BYTE
),
124 FD_ENTRY(FRM_OuterOffsetTop
, fd_OuterY1
, PKCTRL_BYTE
),
125 FD_ENTRY(FRM_OuterOffsetBottom
, fd_OuterY2
, PKCTRL_BYTE
),
126 FD_ENTRY(FRM_InnerOffsetLeft
, fd_InnerX1
, PKCTRL_BYTE
),
127 FD_ENTRY(FRM_InnerOffsetRight
, fd_InnerX2
, PKCTRL_BYTE
),
128 FD_ENTRY(FRM_InnerOffsetTop
, fd_InnerY1
, PKCTRL_BYTE
),
129 FD_ENTRY(FRM_InnerOffsetBottom
, fd_InnerY2
, PKCTRL_BYTE
),
131 FD_FLAG(FRM_EdgesOnly
, FRF_EDGES_ONLY
),
132 FD_FLAG(FRM_Recessed
, FRF_RECESSED
),
133 FD_FLAG(FRM_CenterTitle
, FRF_CENTER_TITLE
),
134 FD_FLAG(FRM_HighlightTitle
, FRF_HIGHLIGHT_TITLE
),
135 FD_FLAG(FRM_ThinFrame
, FRF_THIN_FRAME
),
136 FD_FLAG(FRM_TitleLeft
, FRF_TITLE_LEFT
),
137 FD_FLAG(FRM_TitleRight
, FRF_TITLE_RIGHT
),
144 * Built-in background hook. This hook will take
145 * care of the backfilling rasters and the special
148 //STATIC SAVEDS ASM BuiltInBack(REG(a0) struct Hook *hook, REG(a2) Object *obj, REG(a1) struct FrameDrawMsg *fdm)
149 STATIC SAVEDS ASM
REGFUNC3(IPTR
, BuiltInBack
,
150 REGPARAM(A0
, struct Hook
*, hook
),
151 REGPARAM(A2
, Object
*, obj
),
152 REGPARAM(A1
, struct FrameDrawMsg
*, fdm
))
154 FD
*fd
= INST_DATA(OCLASS(obj
), obj
);
155 UWORD
*pens
= PENS(fdm
->fdm_DrawInfo
), apen
, bpen
= 0;
156 struct RastPort
*rp
= fdm
->fdm_RPort
;
158 struct bguiPattern
*pat
;
162 int x1
= fdm
->fdm_Bounds
->MinX
;
163 int x2
= fdm
->fdm_Bounds
->MaxX
;
164 int y1
= fdm
->fdm_Bounds
->MinY
;
165 int y2
= fdm
->fdm_Bounds
->MaxY
;
167 BOOL sel
= ((fdm
->fdm_State
== IDS_SELECTED
) || (fdm
->fdm_State
== IDS_INACTIVESELECTED
));
169 STATIC UBYTE backfill
[][2] =
171 { BACKGROUNDPEN
, BACKGROUNDPEN
}, // STANDARD_FILL
172 { SHINEPEN
, BACKGROUNDPEN
}, // SHINE_RASTER
173 { SHADOWPEN
, BACKGROUNDPEN
}, // SHADOW_RASTER
174 { SHINEPEN
, SHADOWPEN
}, // SHINE_SHADOW_RASTER
175 { FILLPEN
, BACKGROUNDPEN
}, // FILL_RASTER
176 { SHINEPEN
, FILLPEN
}, // SHINE_FILL_RASTER
177 { SHADOWPEN
, FILLPEN
}, // SHADOW_FILL_RASTER
178 { SHINEPEN
, SHINEPEN
}, // SHINE_BLOCK
179 { SHADOWPEN
, SHADOWPEN
}, // SHADOW_BLOCK
180 { FILLPEN
, FILLPEN
}, // FILL_BLOCK
184 * Render the backfill?
186 if (fdm
->fdm_MethodID
== FRM_RENDER
)
193 ib
.Width
= x2
- x1
+ 1;
194 ib
.Height
= y2
- y1
+ 1;
196 pat
= fd
->fd_Pattern
;
197 if (sel
&& !pat
) pat
= fd
->fd_SelPattern
;
201 BGUI_FillRectPattern(rp
, pat
, x1
, y1
, x2
, y2
);
205 if (fd
->fd_BackFill
== STANDARD_FILL
)
208 * A raster backfill. Set up the pens.
212 * First check for a normal (dri)pen.
213 * If none is given we use the default color.
215 if ((apen
= fd
->fd_BackPen
) != (UWORD
)~0)
217 if (fd
->fd_Flags
& FRF_BACKDRI
) apen
= pens
[apen
];
219 if ((bpen
= fd
->fd_BackPen2
) == (UWORD
)~0)
225 if (fd
->fd_Flags
& FRF_SELDRI2
) bpen
= pens
[bpen
];
229 if (sel
&& (fd
->fd_SelPen
!= (UWORD
)~0))
232 * First check for a selected (dri)pen.
233 * If none is given we use the default color.
235 if ((apen
= fd
->fd_SelPen
) != (UWORD
)~0)
237 if (fd
->fd_Flags
& FRF_SELDRI
) apen
= pens
[apen
];
239 if ((bpen
= fd
->fd_SelPen2
) == (UWORD
)~0)
245 if (fd
->fd_Flags
& FRF_SELDRI2
) bpen
= pens
[bpen
];
250 if (apen
== (UWORD
)~0)
255 * NeXT, DropBox and Ridge frames do not support a SELECTED state
256 * so we force the BACKGROUNDPEN for these types.
261 case FRTYPE_FUZZ_RIDGE
:
262 case FRTYPE_RADIOBUTTON
:
263 apen
= BACKGROUNDPEN
;
268 * Check the state of the frame
270 switch (fdm
->fdm_State
)
275 case IDS_INACTIVESELECTED
:
276 case IDS_INACTIVENORMAL
:
277 apen
= BACKGROUNDPEN
;
281 * And BACKGROUNDPEN for normal frames.
283 apen
= ((fd
->fd_Flags
& FRF_INBORDER
) || (fd
->fd_Type
== FRTYPE_BORDER
)) ? FILLPEN
: BACKGROUNDPEN
;
287 apen
= bpen
= pens
[apen
];
292 fill
= fd
->fd_BackFill
;
293 if (fill
> FILL_BLOCK
) fill
= 0;
295 apen
= pens
[backfill
[fill
][0]];
296 bpen
= pens
[backfill
[fill
][1]];
302 RenderBackFillRaster(rp
, &ib
, apen
, bpen
);
312 * Frame background routine.
314 METHOD(FrameClassBackfill
, struct fmBackfill
*, fmb
)
316 FD
*fd
= INST_DATA(cl
, obj
);
317 struct FrameDrawMsg fdraw
;
320 * Setup framedraw message.
322 fdraw
.fdm_MethodID
= FRM_RENDER
;
323 fdraw
.fdm_RPort
= fmb
->fmb_BInfo
->bi_RPort
;
324 fdraw
.fdm_DrawInfo
= fmb
->fmb_BInfo
->bi_DrInfo
;
325 fdraw
.fdm_Bounds
= fmb
->fmb_Bounds
;
326 fdraw
.fdm_State
= fmb
->fmb_State
;
329 * Call the custom back-fill hook routine.
330 * Note that this can also be the default backfill hook
331 * which is defined above.
333 BGUI_CallHookPkt(fd
->fd_BackFillHook
, (VOID
*)obj
, (VOID
*)&fdraw
);
339 #define Line(x1,y1,x2,y2) { Move(rp, x1, y1); Draw(rp, x2, y2); }
340 #define Point(x1,y1) WritePixel(rp, x1, y1)
344 * Render the radio button frame
346 STATIC VOID
RenderRadioFrame(struct bmRender
*bmr
, WORD l
, WORD t
, WORD r
, WORD b
, FD
*fd
)
348 struct BaseInfo
*bi
= bmr
->bmr_BInfo
;
349 struct RastPort
*rp
= bi
->bi_RPort
;
351 BOOL normal
= !(fd
->fd_Flags
& FRF_RECESSED
);
352 BOOL thin
= fd
->fd_Flags
& FRF_THIN_FRAME
;
355 * Check if we need to draw a normal or a selected frame
357 switch (bmr
->bmr_Flags
)
360 case IDS_INACTIVESELECTED
:
366 * Draw the shine side of the frame
370 *a
++ = l
+ 2; *a
++ = t
;
371 *a
++ = l
; *a
++ = t
+ 2;
372 *a
++ = l
; *a
++ = b
- 2;
373 *a
++ = l
+ 2; *a
++ = b
;
374 *a
++ = l
+ 2; *a
++ = b
- 1;
381 *a
++ = l
+ 1; *a
++ = b
- 2;
382 *a
++ = l
+ 1; *a
++ = t
+ 2;
383 *a
++ = l
+ 2; *a
++ = t
+ 1;
386 BSetDPenA(bi
, normal
? SHINEPEN
: SHADOWPEN
);
388 PolyDraw(rp
, (a
- array
) >> 1, array
);
391 * Draw the shadow side of the frame
395 *a
++ = r
- 2; *a
++ = b
;
396 *a
++ = r
; *a
++ = b
- 2;
397 *a
++ = r
; *a
++ = t
+ 2;
398 *a
++ = r
- 2; *a
++ = t
;
399 *a
++ = r
- 2; *a
++ = t
+ 1;
406 *a
++ = r
- 1; *a
++ = t
+ 2;
407 *a
++ = r
- 1; *a
++ = b
- 2;
408 *a
++ = r
- 2; *a
++ = b
- 1;
411 BSetDPenA(bi
, normal
? SHADOWPEN
: SHINEPEN
);
413 PolyDraw(rp
, (a
- array
) >> 1, array
);
418 * Render the tab frame.
420 STATIC VOID
RenderTabFrame(struct bmRender
*bmr
, int l0
, int t0
, int r0
, int b0
, FD
*fd
)
422 struct BaseInfo
*bi
= bmr
->bmr_BInfo
;
423 struct RastPort
*rp
= bi
->bi_RPort
;
425 int l1
= l0
+ 1, l2
= l0
+ 2, l3
= l0
+ 3, l4
= l0
+ 4;
426 int r1
= r0
- 1, r2
= r0
- 2, r3
= r0
- 3, r4
= r0
- 4;
427 int t1
= t0
+ 1, t2
= t0
+ 2, t3
= t0
+ 3; //, t4 = t0 + 4;
428 int b1
= b0
- 1, b2
= b0
- 2, b3
= b0
- 3; //, b4 = b0 - 4;
430 BOOL sel
= ((bmr
->bmr_Flags
== IDS_SELECTED
) || (bmr
->bmr_Flags
== IDS_INACTIVESELECTED
));
431 BOOL thin
= fd
->fd_Flags
& FRF_THIN_FRAME
;
439 BSetDPenA(bi
, SHINEPEN
);
443 Line(l1
, t2
, l1
, b1
); if (!thin
) Line(l2
, t2
, l2
, b1
);
444 Line(l2
, t1
, l3
, t1
);
445 Line(l3
, t0
, r3
, t0
);
449 Line(l0
, b0
, r0
, b0
);
450 Line(l2
, t3
, l2
, b1
); if (!thin
) Line(l3
, t3
, l3
, b1
);
451 Line(l3
, t2
, l4
, t2
);
452 Line(l4
, t1
, r4
, t1
);
458 BSetDPenA(bi
, SHADOWPEN
);
461 Line(r2
, t1
, r3
, t1
);
462 Line(r1
, t2
, r1
, b1
); if (!thin
) Line(r2
, t2
, r2
, b1
);
467 Line(r3
, t2
, r4
, t2
);
468 Line(r2
, t3
, r2
, b1
); if (!thin
) Line(r3
, t3
, r3
, b1
);
472 case FRTYPE_TAB_BOTTOM
:
476 BSetDPenA(bi
, SHINEPEN
);
480 Line(l1
, t1
, l1
, b2
); if (!thin
) Line(l2
, t1
, l2
, b2
);
481 Line(l2
, b1
, l3
, b1
);
485 Line(l2
, t1
, l2
, b3
); if (!thin
) Line(l3
, t1
, l3
, b3
);
486 Line(l3
, b2
, l4
, b2
);
492 BSetDPenA(bi
, SHADOWPEN
);
496 Line(r3
, b1
, r2
, b1
);
497 Line(r1
, t1
, r1
, b2
); if (!thin
) Line(r2
, t1
, r2
, b2
);
498 Line(l3
, b0
, r3
, b0
);
502 Line(l0
, t0
, r0
, t0
);
503 Line(r4
, b2
, r3
, b2
);
504 Line(r2
, t1
, r2
, b3
); if (!thin
) Line(r3
, t1
, r3
, b3
);
505 Line(l4
, b1
, r4
, b1
);
513 * Render the XEN button frame.
515 STATIC VOID
RenderXenFrame(struct bmRender
*bmr
, WORD l
, WORD t
, WORD r
, WORD b
, FD
*fd
)
517 struct BaseInfo
*bi
= bmr
->bmr_BInfo
;
518 struct RastPort
*rp
= bi
->bi_RPort
;
521 * Setup pen for the XEN lines
522 * around the normal button frame.
524 BSetDPenA(bi
, SHADOWPEN
);
532 HLine(rp
, l
, t
- 1, r
);
533 VLine(rp
, r
- 1, t
, b
);
534 HLine(rp
, l
, b
- 1, r
);
535 VLine(rp
, l
- 1, t
, b
);
540 RenderBevelBox(bi
, l
, t
, r
, b
, bmr
->bmr_Flags
, fd
->fd_Flags
& FRF_RECESSED
, fd
->fd_Flags
& FRF_THIN_FRAME
);
545 * Pass on the frame thickness.
547 STATIC ASM VOID
FrameThickness(REG(a0
) Class
*cl
, REG(a2
) Object
*obj
)
549 FD
*fd
= INST_DATA(cl
, obj
);
550 struct ThicknessMsg tm
;
555 STATIC UBYTE thick
[][4] =
557 { 1, 1, 1, 1 }, // FRTYPE_CUSTOM
558 { 2, 1, 1, 1 }, // FRTYPE_BUTTON
559 { 4, 2, 2, 2 }, // FRTYPE_RIDGE
560 { 6, 3, 3, 3 }, // FRTYPE_DROPBOX
561 { 4, 2, 2, 2 }, // FRTYPE_NEXT
562 { 1, 1, 1, 1 }, // FRTYPE_RADIOBUTTON
563 { 3, 2, 2, 2 }, // FRTYPE_XEN_BUTTON
564 { 2, 1, 1, 1 }, // FRTYPE_TAB_ABOVE
565 { 2, 1, 1, 1 }, // FRTYPE_TAB_BELOW
566 { 1, 1, 1, 1 }, // FRTYPE_BORDER
567 { 0, 0, 0, 0 }, // FRTYPE_NONE
568 { 3, 2, 3, 3 }, // FRTYPE_FUZZ_BUTTON
569 { 3, 2, 3, 3 }, // FRTYPE_FUZZ_RIDGE
570 { 6, 2, 5, 2 }, // FRTYPE_TAB_TOP
571 { 6, 2, 5, 2 }, // FRTYPE_TAB_BOTTOM
572 { 2, 6, 2, 5 }, // FRTYPE_TAB_LEFT
573 { 2, 6, 2, 5 }, // FRTYPE_TAB_RIGHT
576 if (!(fd
->fd_Flags
& FRF_CUST_THICK
))
578 thin
= fd
->fd_Flags
& FRF_THIN_FRAME
;
583 if (fd
->fd_FrameHook
)
586 * Yes. Call it to get the thickness
587 * of the custom frame.
589 tm
.tm_MethodID
= FRM_THICKNESS
;
590 tm
.tm_Thickness
.Horizontal
= &h
;
591 tm
.tm_Thickness
.Vertical
= &v
;
595 * If this method is not understood
596 * by the hook we use default values.
598 if (BGUI_CallHookPkt(fd
->fd_FrameHook
, (VOID
*)obj
, (VOID
*)&tm
) != FRC_OK
)
606 * Setup frame thickness of the internal frames.
609 if (type
> FRTYPE_FUZZ_RIDGE
) type
= 0;
611 h
= thick
[type
][thin
? 2 : 0];
612 v
= thick
[type
][thin
? 3 : 1];
614 fd
->fd_Horizontal
= h
;
620 * Setup frame attributes.
622 STATIC ASM VOID
SetFrameAttrs(REG(a0
) Class
*cl
, REG(a2
) Object
*obj
, REG(a1
) struct TagItem
*attr
)
624 FD
*fd
= INST_DATA(cl
, obj
);
626 IPTR temp
= (IPTR
)NULL
;
627 struct TagItem
*tstate
= attr
;
632 if ((tag
= FindTagItem(FRM_Template
, attr
)))
634 ob
= (Object
*)tag
->ti_Data
;
637 Get_Attr(ob
, FRM_Template
, &temp
);
640 CopyMem((FD
*)temp
, fd
, sizeof(FD
));
641 fd
->fd_Flags
&= ~FRF_SELFOPEN
;
646 BGUI_PackStructureTags((APTR
)fd
, FramePackTable
, attr
);
651 while ((tag
= NextTagItem(&tstate
)))
658 fd
->fd_ParentGroup
= (Object
*)data
;
662 case FRM_FrameHeight
:
663 fd
->fd_Flags
|= FRF_CUST_THICK
;
667 if (fd
->fd_Font
&& (fd
->fd_Flags
& FRF_SELFOPEN
))
668 BGUI_CloseFont(fd
->fd_Font
);
669 fd
->fd_Font
= (struct TextFont
*)data
;
670 fd
->fd_Flags
&= ~FRF_SELFOPEN
;
676 if ((tf
= BGUI_OpenFont((struct TextAttr
*)data
)))
678 if (fd
->fd_Font
&& (fd
->fd_Flags
& FRF_SELFOPEN
))
679 BGUI_CloseFont(fd
->fd_Font
);
681 fd
->fd_TitleFont
= (struct TextAttr
*)data
;
682 fd
->fd_Flags
|= FRF_SELFOPEN
;
688 fd
->fd_BackFill
= data
;
689 fd
->fd_BackFillHook
= NULL
;
690 fd
->fd_Flags
&= ~FRF_EDGES_ONLY
;
693 case FRM_BackRasterPen
:
694 fd
->fd_BackPen2
= data
;
695 fd
->fd_Flags
&= ~FRF_BACKDRI2
;
696 if (fd
->fd_BackPen
!= (UWORD
)~0) break;
698 fd
->fd_BackPen
= data
;
699 fd
->fd_Flags
&= ~FRF_BACKDRI
;
702 case FRM_BackRasterDriPen
:
703 fd
->fd_BackPen2
= data
;
704 fd
->fd_Flags
|= FRF_BACKDRI2
;
705 if (fd
->fd_BackPen
!= (UWORD
)~0) break;
707 fd
->fd_BackPen
= data
;
708 fd
->fd_Flags
|= FRF_BACKDRI
;
711 case FRM_SelectedBackRasterPen
:
712 fd
->fd_SelPen2
= data
;
713 fd
->fd_Flags
&= ~FRF_SELDRI2
;
714 if (fd
->fd_SelPen
!= (UWORD
)~0) break;
715 case FRM_SelectedBackPen
:
716 fd
->fd_SelPen
= data
;
717 fd
->fd_Flags
&= ~FRF_SELDRI
;
720 case FRM_SelectedBackRasterDriPen
:
721 fd
->fd_SelPen2
= data
;
722 fd
->fd_Flags
|= FRF_SELDRI2
;
723 if (fd
->fd_SelPen
!= (UWORD
)~0) break;
724 case FRM_SelectedBackDriPen
:
725 fd
->fd_SelPen
= data
;
726 fd
->fd_Flags
|= FRF_SELDRI
;
730 if (!fd
->fd_Title
&& data
)
731 fd
->fd_Title
= BGUI_NewObject(BGUI_TEXT_GRAPHIC
, TEXTA_CopyText
, TRUE
, TAG_DONE
);
735 DoSetMethodNG(fd
->fd_Title
, TEXTA_Text
, data
, TAG_DONE
);
738 DisposeObject(fd
->fd_Title
);
745 if (!fd
->fd_Title
) fd
->fd_Title
= BGUI_NewObject(BGUI_TEXT_GRAPHIC
, TEXTA_CopyText
, TRUE
, TAG_DONE
);
746 if (fd
->fd_Title
) DoSetMethodNG(fd
->fd_Title
, TEXTA_TextID
, data
, TAG_DONE
);
753 if (data
) fd
->fd_Flags
|= FRF_INBORDER
;
754 else fd
->fd_Flags
&= ~FRF_INBORDER
;
757 case FRM_FillPattern
:
758 fd
->fd_Pattern
= (struct bguiPattern
*)data
;
761 case FRM_SelectedFillPattern
:
762 fd
->fd_SelPattern
= (struct bguiPattern
*)data
;
765 case FRM_BackFillHook
:
766 fd
->fd_BackFillHook
= (struct Hook
*)data
;
770 fd
->fd_FrameHook
= (struct Hook
*)data
;
774 FrameThickness(cl
, obj
);
782 if (fd
->fd_FrameHook
) fd
->fd_Type
= FRTYPE_CUSTOM
;
783 else if (!fd
->fd_Type
) fd
->fd_Type
= FRTYPE_BUTTON
;
785 if (fd
->fd_BackFillHook
== NULL
)
786 fd
->fd_BackFillHook
= &fd
->fd_DefBackfill
;
791 case FRTYPE_TAB_BOTTOM
:
792 case FRTYPE_TAB_LEFT
:
793 case FRTYPE_TAB_RIGHT
:
794 fd
->fd_Flags
|= FRF_FILL_OUTER
;
797 fd
->fd_Flags
&= ~FRF_FILL_OUTER
;
804 * Create a shiny new object.
806 METHOD(FrameClassNew
, struct opSet
*, ops
)
812 * First we let the superclass
813 * create a new object.
815 if ((rc
= AsmDoSuperMethodA(cl
, obj
, (Msg
)ops
)))
818 * Get us the instance data.
820 fd
= INST_DATA(cl
, rc
);
825 fd
->fd_Type
= FRTYPE_BUTTON
;
826 fd
->fd_BackPen
= (UWORD
)~0;
827 fd
->fd_SelPen
= (UWORD
)~0;
828 fd
->fd_BackPen2
= (UWORD
)~0;
829 fd
->fd_SelPen2
= (UWORD
)~0;
831 fd
->fd_DefBackfill
.h_Entry
= (HOOKFUNC
)BuiltInBack
;
836 SetFrameAttrs(cl
, (Object
*)rc
, ops
->ops_AttrList
);
837 FrameThickness(cl
, (Object
*)rc
);
846 * Change one or more attrubutes.
848 METHOD(FrameClassSet
, struct opSet
*, ops
)
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
);
876 Tag tag
= opg
->opg_AttrID
;
877 IPTR
*store
= opg
->opg_Storage
;
880 * First we see if the attribute
881 * they want is known to us. If not
882 * we pass it onto the superclass.
891 STORE fd
->fd_TitleFont
;
895 STORE fd
->fd_FrameHook
;
898 case FRM_BackFillHook
:
899 STORE fd
->fd_BackFillHook
;
902 case FRM_FillPattern
:
903 STORE fd
->fd_Pattern
;
906 case FRM_SelectedFillPattern
:
907 STORE fd
->fd_SelPattern
;
911 STORE fd
->fd_Horizontal
;
913 case FRM_FrameHeight
:
914 STORE fd
->fd_Vertical
;
918 STORE fd
->fd_Flags
& FRF_BACKDRI
? ~0 : fd
->fd_BackPen
;
921 STORE fd
->fd_Flags
& FRF_BACKDRI
? fd
->fd_BackPen
: ~0;
923 case FRM_SelectedBackPen
:
924 STORE fd
->fd_Flags
& FRF_SELDRI
? ~0 : fd
->fd_SelPen
;
926 case FRM_SelectedBackDriPen
:
927 STORE fd
->fd_Flags
& FRF_SELDRI
? fd
->fd_SelPen
: ~0;
929 case FRM_BackRasterPen
:
930 STORE fd
->fd_Flags
& FRF_BACKDRI2
? ~0 : fd
->fd_BackPen2
;
932 case FRM_BackRasterDriPen
:
933 STORE fd
->fd_Flags
& FRF_BACKDRI2
? fd
->fd_BackPen2
: ~0;
935 case FRM_SelectedBackRasterPen
:
936 STORE fd
->fd_Flags
& FRF_SELDRI2
? ~0 : fd
->fd_SelPen2
;
938 case FRM_SelectedBackRasterDriPen
:
939 STORE fd
->fd_Flags
& FRF_SELDRI2
? fd
->fd_SelPen2
: ~0;
943 rc
= BGUI_UnpackStructureTag((UBYTE
*)fd
, FramePackTable
, tag
, store
);
944 if (!rc
) rc
= AsmDoSuperMethodA(cl
, obj
, (Msg
)opg
);
953 * Dispose of the object.
955 METHOD(FrameClassDispose
, Msg
, msg
)
957 FD
*fd
= INST_DATA(cl
, obj
);
962 if (fd
->fd_Font
&& (fd
->fd_Flags
& FRF_SELFOPEN
))
963 BGUI_CloseFont(fd
->fd_Font
);
966 * Dispose of the text graphic.
968 if (fd
->fd_Title
) DisposeObject(fd
->fd_Title
);
971 * The rest goes to the superclass.
973 return AsmDoSuperMethodA(cl
, obj
, msg
);
977 /// FRAMEM_SETUPBOUNDS
979 METHOD(FrameClassSetupBounds
, struct fmSetupBounds
*, fmsb
)
981 FD
*fd
= INST_DATA(cl
, obj
);
982 struct IBox
*hb
= fmsb
->fmsb_HitBox
;
983 struct IBox
*ib
= fmsb
->fmsb_InnerBox
;
984 int ox1
= fd
->fd_OuterX1
;
985 int ox2
= fd
->fd_OuterX2
;
986 int oy1
= fd
->fd_OuterY1
;
987 int oy2
= fd
->fd_OuterY2
;
991 hb
->Width
-= ox1
+ ox2
;
992 hb
->Height
-= oy1
+ oy2
;
994 ox1
+= fd
->fd_InnerX1
+ fd
->fd_Horizontal
;
995 ox2
+= fd
->fd_InnerX2
+ fd
->fd_Horizontal
;
996 oy1
+= fd
->fd_InnerY1
+ fd
->fd_Vertical
;
997 oy2
+= fd
->fd_InnerY2
+ fd
->fd_Vertical
;
1001 if (fd
->fd_Font
) oy1
+= fd
->fd_Font
->tf_YSize
;
1002 else if (fd
->fd_TitleFont
) oy1
+= fd
->fd_TitleFont
->ta_YSize
;
1007 ib
->Width
-= ox1
+ ox2
;
1008 ib
->Height
-= oy1
+ oy2
;
1010 SetImageBounds(obj
, fmsb
->fmsb_HitBox
);
1018 METHOD(FrameClassDimensions
, struct bmDimensions
*, bmd
)
1020 FD
*fd
= INST_DATA(cl
, obj
);
1021 struct bguiExtent
*be
= bmd
->bmd_Extent
;
1022 int ox
= (fd
->fd_Horizontal
<< 1) + fd
->fd_InnerX1
+ fd
->fd_InnerX2
;
1023 int oy
= (fd
->fd_Vertical
<< 1) + fd
->fd_InnerY1
+ fd
->fd_InnerY2
;
1027 if (fd
->fd_Font
) oy
+= fd
->fd_Font
->tf_YSize
;
1028 else if (fd
->fd_TitleFont
) oy
+= fd
->fd_TitleFont
->ta_YSize
;
1031 be
->be_Min
.Width
+= ox
;
1032 be
->be_Min
.Height
+= oy
;
1034 be
->be_Nom
.Width
+= ox
;
1035 be
->be_Nom
.Height
+= oy
;
1045 METHOD(FrameClassRender
, struct bmRender
*, bmr
)
1047 FD
*fd
= INST_DATA(cl
, obj
);
1048 struct BaseInfo
*bi
= bmr
->bmr_BInfo
;
1049 struct RastPort
*rp
= bi
->bi_RPort
;
1050 struct Rectangle rect
;
1051 struct FrameDrawMsg fdraw
;
1052 WORD l
, t
, r
, b
, place
;
1054 int tv
, th
, dv
, dh
, shadow
, shine
, tmp
= 0, tmp2
= 0;
1055 int state
= bmr
->bmr_Flags
;
1056 int i_fuzz
, i_blank
, i_swap
, i_mix
;
1059 static UWORD pat
[] = { 0x5555, 0xAAAA };
1061 static BYTE taboff
[4][4][2] =
1063 { { 3, 2 }, { 3, 2 }, { 2, 1 }, { 0, 0 } },
1064 { { 3, 2 }, { 3, 2 }, { 0, 0 }, { 2, 1 } },
1065 { { 2, 1 }, { 0, 0 }, { 3, 2 }, { 3, 2 } },
1066 { { 0, 0 }, { 2, 1 }, { 3, 2 }, { 3, 2 } },
1072 * Calculate the frame position and dimensions
1074 l
= IMAGE(obj
)->LeftEdge
;
1075 t
= IMAGE(obj
)->TopEdge
;
1076 r
= IMAGE(obj
)->Width
+ l
- 1;
1077 b
= IMAGE(obj
)->Height
+ t
- 1;
1082 * Setup the font if one is present.
1084 if (fd
->fd_Font
) BSetFont(bi
, fd
->fd_Font
);
1087 * Adjust top position if there is a title present.
1089 if (fd
->fd_Flags
& FRF_CENTER_TITLE
)
1090 t
+= (rp
->TxBaseline
- (rp
->TxHeight
>> 1));
1092 t
+= rp
->TxBaseline
;
1100 * First we do the background.
1102 * When this is a FRF_EDGES_ONLY frame we do nothing.
1103 * No hooks are called, and nothing is filled.
1105 if (!(fd
->fd_Flags
& FRF_EDGES_ONLY
))
1107 if (fd
->fd_Flags
& FRF_FILL_OUTER
)
1109 if ((fr
= fd
->fd_ParentGroup
? BASE_DATA(fd
->fd_ParentGroup
)->bc_Frame
: NULL
))
1111 AsmDoMethod(fr
, FRAMEM_BACKFILL
, bi
, &rect
, IDS_NORMAL
);
1115 BSetDPenA(bi
, BACKGROUNDPEN
);
1116 BRectFillA(bi
, &rect
);
1118 tmp
= fd
->fd_Type
- FRTYPE_TAB_TOP
;
1119 tmp2
= ((state
== IDS_SELECTED
) || (state
== IDS_SELECTED
)) ? 1 : 0;
1121 rect
.MinX
+= taboff
[tmp
][0][tmp2
];
1122 rect
.MaxX
-= taboff
[tmp
][1][tmp2
];
1123 rect
.MinY
+= taboff
[tmp
][2][tmp2
];
1124 rect
.MaxY
-= taboff
[tmp
][3][tmp2
];
1128 AsmDoMethod(obj
, FRAMEM_BACKFILL
, bi
, &rect
, state
);
1132 * Get frame thickness.
1134 th
= fd
->fd_Horizontal
;
1135 tv
= fd
->fd_Vertical
;
1137 if ((th
<< 1) > (r
- l
+ 1)) th
= (r
- l
+ 1) >> 1;
1138 if ((tv
<< 1) > (b
- t
+ 1)) tv
= (b
- t
+ 1) >> 1;
1141 * Draw the frame (whatever type it is)
1143 state
= bmr
->bmr_Flags
;
1146 * Selected or normal?
1151 case IDS_INACTIVESELECTED
:
1163 * Swap pens if we must
1166 if (fd
->fd_Flags
& FRF_RECESSED
)
1176 switch (fd
->fd_Type
)
1180 * Fill in the data structures for the custom frame hook
1182 fdraw
.fdm_MethodID
= FRM_RENDER
;
1183 fdraw
.fdm_RPort
= rp
;
1184 fdraw
.fdm_DrawInfo
= bi
->bi_DrInfo
;
1185 fdraw
.fdm_Bounds
= &rect
;
1186 fdraw
.fdm_State
= state
;
1187 fdraw
.fdm_Horizontal
= th
;
1188 fdraw
.fdm_Vertical
= tv
;
1190 * Call the hook routine.
1192 rc
= BGUI_CallHookPkt(fd
->fd_FrameHook
, (VOID
*)obj
, (VOID
*)&fdraw
);
1197 case FRTYPE_DROPBOX
:
1198 case FRTYPE_FUZZ_BUTTON
:
1199 case FRTYPE_FUZZ_RIDGE
:
1206 dv
= (tv
+ th
- 1) / th
; if (dv
< 1) dv
= 1;
1207 dh
= (th
+ tv
- 1) / tv
; if (dh
< 1) dh
= 1;
1209 if (fd
->fd_Type
== FRTYPE_FUZZ_BUTTON
)
1212 * 1/4 Normal, 3/4 Raster
1214 i_fuzz
= (tv
/ dv
) / 4;
1216 if (fd
->fd_Type
== FRTYPE_FUZZ_RIDGE
)
1219 * 1/3 Normal, 1/3 Blank, 1/3 Recessed
1223 i_mix
= (tv
/ dv
) / 3 - 1;
1224 i_swap
= (2 * tv
/ dv
) / 3 - 1;
1226 if (fd
->fd_Type
== FRTYPE_DROPBOX
)
1229 * 1/3 Normal, 1/3 Blank, 1/3 Recessed
1233 i_blank
= (tv
/ dv
) / 3 - 1;
1234 i_swap
= (2 * tv
/ dv
) / 3 - 1;
1236 if (fd
->fd_Type
== FRTYPE_NEXT
)
1239 * 1/2 Recessed, 1/2 Normal
1245 i_swap
= (tv
/ dv
) / 2 - 1;
1247 if (fd
->fd_Type
== FRTYPE_RIDGE
)
1250 * 1/2 Normal, 1/2 Recessed
1254 i_swap
= (tv
/ dv
) / 2 - 1;
1258 * Render the bevelbox.
1260 while ((tv
> 0) && (th
> 0))
1262 if (shine
>= 0) BSetDPenA(bi
, shine
);
1265 BRectFill(bi
, l
, t
, l
+ dh
- 1, b
);
1267 if (shadow
>= 0) BSetDPenA(bi
, shadow
);
1270 BRectFill(bi
, l
, b
- dv
+ 1, r
, b
);
1274 BRectFill(bi
, r
- dh
+ 1, t
, r
, b
); r
-= dh
;
1275 if (shine
>= 0) BSetDPenA(bi
, shine
);
1278 BRectFill(bi
, l
, t
, r
, t
+ dv
- 1);
1285 BSetAfPt(bi
, pat
, 1);
1289 shine
= BACKGROUNDPEN
;
1290 shadow
= BACKGROUNDPEN
;
1300 BSetAfPt(bi
, pat
, 1);
1301 BSetDPenA(bi
, shine
);
1302 BSetDPenB(bi
, shadow
);
1303 shine
= shadow
= -1;
1308 BSetDPenA(bi
, shine
);
1309 BRectFill(bi
, l
, t
, r
, t
+ tv
- 1);
1310 BSetDPenA(bi
, shadow
);
1311 BRectFill(bi
, l
, b
- tv
+ 1, r
, b
);
1315 BSetDPenA(bi
, shine
);
1316 BRectFill(bi
, l
, t
, l
+ th
- 1, b
);
1317 BSetDPenA(bi
, shadow
);
1318 BRectFill(bi
, r
- th
+ 1, t
, r
, b
);
1322 case FRTYPE_RADIOBUTTON
:
1323 RenderRadioFrame(bmr
, l
, t
, r
, b
, fd
);
1326 case FRTYPE_XEN_BUTTON
:
1327 RenderXenFrame(bmr
, l
, t
, r
, b
, fd
);
1330 case FRTYPE_TAB_TOP
:
1331 case FRTYPE_TAB_BOTTOM
:
1332 case FRTYPE_TAB_LEFT
:
1333 case FRTYPE_TAB_RIGHT
:
1334 RenderTabFrame(bmr
, l
, t
, r
, b
, fd
);
1337 case FRTYPE_TAB_ABOVE
:
1341 BSetDPenA(bi
, shine
);
1342 BRectFill(bi
, l
, t
, l
+ th
- 1, b
- tv
);
1343 BSetDPenA(bi
, shadow
);
1344 BRectFill(bi
, l
+ 1, b
- tv
+ 1, r
, b
);
1345 BRectFill(bi
, r
- th
+ 1, t
, r
, b
);
1348 case FRTYPE_TAB_BELOW
:
1352 BSetDPenA(bi
, shine
);
1353 BRectFill(bi
, l
, t
, l
+ th
- 1, b
- tv
+ 1);
1354 BRectFill(bi
, l
, t
, r
- th
+ 1, t
+ tv
- 1);
1355 BSetDPenA(bi
, shadow
);
1356 BRectFill(bi
, r
- th
+ 1, t
, r
, b
);
1361 * Render the borderbox.
1363 RenderBevelBox(bi
, l
, t
, r
, b
, state
, fd
->fd_Flags
& FRF_RECESSED
, TRUE
);
1372 * Render frame the title.
1381 if (fd
->fd_Flags
& FRF_TITLE_LEFT
) place
= 1;
1382 else if (fd
->fd_Flags
& FRF_TITLE_RIGHT
) place
= 2;
1387 RenderTitle(fd
->fd_Title
, bi
, l
, t
, r
- l
+ 1,
1388 fd
->fd_Flags
& FRF_HIGHLIGHT_TITLE
, fd
->fd_Flags
& FRF_CENTER_TITLE
, place
);
1398 METHOD(FrameClassLocalize
, struct bmLocalize
*, bml
)
1400 FD
*fd
= INST_DATA(cl
, obj
);
1403 if (fd
->fd_Title
) rc
= AsmDoMethodA(fd
->fd_Title
, (Msg
)bml
);
1409 /// Class initialization.
1412 * Class function table.
1414 STATIC DPFUNC ClassFunc
[] = {
1415 { BASE_RENDER
, FrameClassRender
, },
1416 { BASE_DIMENSIONS
, FrameClassDimensions
, },
1417 { FRAMEM_BACKFILL
, FrameClassBackfill
, },
1418 { FRAMEM_SETUPBOUNDS
, FrameClassSetupBounds
, },
1419 { OM_SET
, FrameClassSet
, },
1420 { OM_GET
, FrameClassGet
, },
1421 { OM_NEW
, FrameClassNew
, },
1422 { OM_DISPOSE
, FrameClassDispose
, },
1423 { BASE_LOCALIZE
, FrameClassLocalize
, },
1428 * Simple class initialization.
1430 makeproto Class
*InitFrameClass(void)
1432 return BGUI_MakeClass(CLASS_SuperClassBGUI
, BGUI_IMAGE_OBJECT
,
1433 CLASS_ObjectSize
, sizeof(FD
),
1434 CLASS_DFTable
, ClassFunc
,