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.2 2004/06/16 20:16:48 verhaegs
15 * Use METHODPROTO, METHOD_END and REGFUNCPROTOn where needed.
17 * Revision 42.1 2000/05/15 19:27:02 stegerg
18 * another hundreds of REG() macro replacements in func headers/protos.
20 * Revision 42.0 2000/05/09 22:09:53 mlemos
21 * Bumped to revision 42.0 before handing BGUI to AROS team
23 * Revision 41.11 2000/05/09 19:54:53 mlemos
24 * Merged with the branch Manuel_Lemos_fixes.
26 * Revision 41.10.2.3 1999/07/23 19:44:34 mlemos
27 * Added missing setting of text pen to draw the progress done value.
28 * Ensured that text drawing is done in complement mode if the text pen is the
29 * the same as the fill pen or background pen.
31 * Revision 41.10.2.2 1998/11/16 20:00:23 mlemos
32 * Replaced a FreeVec call by BGUI_FreePoolMem.
34 * Revision 41.10.2.1 1998/06/21 21:14:32 mlemos
35 * Prevented the Render method to draw an invalid size bar.
37 * Revision 41.10 1998/02/25 21:12:50 mlemos
40 * Revision 1.1 1998/02/25 17:09:24 mlemos
46 #include "include/classdefs.h"
48 /// Class definitions.
50 * The instance data used by the
51 * objects of this class.
53 typedef struct ProgressData
{
54 LONG pd_Min
; /* minimum progression */
55 LONG pd_Max
; /* maximum progression */
56 LONG pd_Done
; /* current progression */
57 LONG pd_Divisor
; /* Done divisor */
58 UWORD pd_Flags
; /* see below */
63 struct TextFont
*pd_Font
;
66 #define PDF_VERTICAL (1<<0)
71 * Create a shiny new object.
73 METHOD(ProgressClassNew
, struct opSet
*, ops
)
79 tags
= DefTagList(BGUI_PROGRESS_GADGET
, ops
->ops_AttrList
);
82 * Let the superclass setup an object for us.
84 if ((rc
= NewSuperObject(cl
, obj
, tags
)))
86 pd
= INST_DATA(cl
, rc
);
94 AsmDoMethod((Object
*)rc
, OM_SET
, ops
->ops_AttrList
, NULL
);
102 /// OM_SET, OM_UPDATE
104 * Change the object attributes.
106 METHOD(ProgressClassSetUpdate
, struct opUpdate
*, opu
)
108 PD
*pd
= INST_DATA(cl
, obj
);
109 ULONG tmp
, odone
= pd
->pd_Done
;
111 struct TagItem
*attr
= opu
->opu_AttrList
, *tag
;
112 struct TagItem
*tstate
= attr
;
116 * First let the superclass do it's thing.
118 AsmDoSuperMethodA(cl
, obj
, (Msg
)opu
);
121 * Set attributes we know.
123 while ((tag
= NextTagItem(&tstate
)))
126 switch ( tag
->ti_Tag
)
139 pd
->pd_Done
= data
/ pd
->pd_Divisor
;
143 case PROGRESS_Divisor
:
144 pd
->pd_Divisor
= data
? data
: 1;
147 case PROGRESS_FormatString
:
148 pd
->pd_Text
= (UBYTE
*)data
;
152 case PROGRESS_Vertical
:
153 if (data
) pd
->pd_Flags
|= PDF_VERTICAL
;
154 else pd
->pd_Flags
&= ~PDF_VERTICAL
;
159 Get_SuperAttr(cl
, obj
, BT_TextFont
, (IPTR
*)&pd
->pd_Font
);
167 if (pd
->pd_Max
< pd
->pd_Min
)
169 tmp
= pd
->pd_Min
; pd
->pd_Min
= pd
->pd_Max
; pd
->pd_Max
= tmp
;
171 else if (pd
->pd_Max
== pd
->pd_Min
)
174 if (pd
->pd_Done
> pd
->pd_Max
) pd
->pd_Done
= pd
->pd_Max
;
175 else if (pd
->pd_Done
< pd
->pd_Min
) pd
->pd_Done
= pd
->pd_Min
;
178 * Do we need to change visually?
181 DoRenderMethod(obj
, opu
->opu_GInfo
, GREDRAW_UPDATE
);
186 if (odone
!= pd
->pd_Done
)
187 DoNotifyMethod(obj
, opu
->opu_GInfo
, 0, GA_ID
, GADGET(obj
)->GadgetID
, PROGRESS_Done
, pd
->pd_Done
, TAG_END
);
195 * Hmm, they want us out of here.
197 METHOD(ProgressClassDispose
, Msg
, msg
)
199 PD
*pd
= INST_DATA(cl
, obj
);
202 * Deallocate the string buffer.
204 if (pd
->pd_Buffer
) BGUI_FreePoolMem(pd
->pd_Buffer
);
207 * And let the superclass take
210 return AsmDoSuperMethodA(cl
, obj
, msg
);
216 * Scale the area of the indicator
217 * that needs to be filled.
219 #define ScaleFill(s,m,d) UDivMod32( UMult32( d, s ) + UDivMod32( m, 2 ), m )
222 * Render the gadget imagery
224 METHOD(ProgressClassRender
, struct bmRender
*, bmr
)
226 PD
*pd
= INST_DATA(cl
, obj
);
227 BC
*bc
= BASE_DATA(obj
);
228 struct BaseInfo
*bi
= bmr
->bmr_BInfo
;
229 struct RastPort
*rp
= bi
->bi_RPort
;
230 struct IBox box1
, box2
;
236 * Render the baseclass.
238 AsmDoSuperMethodA(cl
, obj
, (Msg
)bmr
);
244 box1
= bc
->bc_InnerBox
;
245 box2
= bc
->bc_InnerBox
;
247 space
= (pd
->pd_Flags
& PDF_VERTICAL
) ? box1
.Height
: box1
.Width
;
252 filled
= ScaleFill(space
, ABS(max
- min
), ABS(done
));
255 * Keep within the bounds.
257 if (done
>= max
) filled
= space
;
258 else if (done
<= min
) filled
= 0;
259 if (filled
> space
) filled
= space
;
262 * Vertical indication?
264 if (!(pd
->pd_Flags
& PDF_VERTICAL
))
268 box2
.Width
-= filled
;
272 box1
.Top
+= box1
.Height
- filled
;
273 box1
.Height
= filled
;
274 box2
.Height
-= filled
;
278 * Convert to Rectangle structures.
279 * Render filled area and clear the rest.
284 box1
.Width
+= box1
.Left
- 1;
285 box1
.Height
+= box1
.Top
- 1;
286 AsmDoMethod(bc
->bc_Frame
, FRAMEM_BACKFILL
, bi
, &box1
, IDS_SELECTED
);
291 box2
.Width
+= box2
.Left
- 1;
292 box2
.Height
+= box2
.Top
- 1;
293 AsmDoMethod(bc
->bc_Frame
, FRAMEM_BACKFILL
, bi
, &box2
, IDS_NORMAL
);
297 * Render textual indicator when present.
304 if (pd
->pd_Font
) BSetFont(bi
, pd
->pd_Font
);
309 if ((str
= DoBuffer(pd
->pd_Text
, &pd
->pd_Buffer
, &pd
->pd_BufSize
, (RAWARG
)&pd
->pd_Done
)) && strlen(str
))
312 STRPTR formatted
=NULL
;
314 BGUI_InfoTextSize(rp
, str
, (UWORD
*)&box1
.Width
, (UWORD
*)&box1
.Height
);
316 box1
.Left
= bc
->bc_InnerBox
.Left
+ ((bc
->bc_InnerBox
.Width
- box1
.Width
) >> 1);
317 box1
.Top
= bc
->bc_InnerBox
.Top
+ ((bc
->bc_InnerBox
.Height
- box1
.Height
) >> 1);
319 FSetAPen(rp
,apen
=bi
->bi_DrInfo
->dri_Pens
[TEXTPEN
]);
320 if((apen
!=bi
->bi_DrInfo
->dri_Pens
[FILLPEN
]
321 && apen
!=bi
->bi_DrInfo
->dri_Pens
[BACKGROUNDPEN
])
322 || (formatted
=BGUI_AllocPoolMem(strlen(ISEQ_COMPLEMENT
)+strlen(str
)+1)))
326 strcpy(formatted
,ISEQ_COMPLEMENT
);
327 strcpy(formatted
+strlen(ISEQ_COMPLEMENT
),str
);
330 RenderText(bi
, str
, &box1
);
332 BGUI_FreePoolMem(formatted
);
342 * They want to know an attribute value.
344 METHOD(ProgressClassGet
, struct opGet
*, opg
)
346 PD
*pd
= INST_DATA(cl
, obj
);
348 IPTR
*store
= opg
->opg_Storage
;
350 switch (opg
->opg_AttrID
)
357 rc
= AsmDoSuperMethodA(cl
, obj
, (Msg
)opg
);
366 * We do not respond to
367 * clicking in the gadget.
369 METHOD(ProgressClassHitTest
, struct gpHitTest
*, gph
)
377 * Our parent group needs to know
378 * something about our dimensions.
380 METHOD(ProgressClassDimensions
, struct bmDimensions
*, bmd
)
382 PD
*pd
= INST_DATA(cl
, obj
);
383 struct RastPort
*rp
= bmd
->bmd_BInfo
->bi_RPort
;
384 UWORD mw
= 2, mh
= 2, l
;
395 if ((str
= DoBuffer(pd
->pd_Text
, &pd
->pd_Buffer
, &pd
->pd_BufSize
, (RAWARG
)&pd
->pd_Min
)))
398 * Compute size of minimum level.
400 l
= TotalWidth(rp
, str
);
405 if ((str
= DoBuffer(pd
->pd_Text
, &pd
->pd_Buffer
, &pd
->pd_BufSize
, (RAWARG
)&pd
->pd_Max
)))
408 * Compute size of maximum level.
410 mw
= TotalWidth (rp
, str
);
411 mh
= TotalHeight(rp
, str
);
416 mw
= (mw
> l
) ? mw
: l
;
419 * Add the width of 2/3 of a single space.
421 mw
+= (TextWidthNum(rp
, " ", 1) / 3);
426 * Setup minimum dimensions.
428 return CalcDimensions(cl
, obj
, bmd
, mw
, mh
);
432 /// Class initialization.
436 STATIC DPFUNC ClassFunc
[] = {
437 { BASE_RENDER
, ProgressClassRender
, },
438 { BASE_DIMENSIONS
, ProgressClassDimensions
, },
440 { OM_NEW
, ProgressClassNew
, },
441 { OM_GET
, ProgressClassGet
, },
442 { OM_SET
, ProgressClassSetUpdate
, },
443 { OM_UPDATE
, ProgressClassSetUpdate
, },
444 { OM_DISPOSE
, ProgressClassDispose
, },
445 { GM_HITTEST
, ProgressClassHitTest
, },
450 * Initialize the progress class.
452 makeproto Class
*InitProgressClass(void)
454 return BGUI_MakeClass(CLASS_SuperClassBGUI
, BGUI_BASE_GADGET
,
455 CLASS_ObjectSize
, sizeof(PD
),
456 CLASS_DFTable
, ClassFunc
,