2 Copyright © 1995-2005, The AROS Development Team. All rights reserved.
5 Internal GadTools text class (NUMERIC_KIND and TEXT_KIND) .
9 #include <proto/exec.h>
10 #include <exec/libraries.h>
11 #include <exec/memory.h>
12 #include <proto/dos.h>
13 #include <intuition/classes.h>
14 #include <intuition/classusr.h>
15 #include <intuition/gadgetclass.h>
16 #include <intuition/imageclass.h>
17 #include <intuition/intuition.h>
18 #include <intuition/cghooks.h>
19 #include <graphics/rastport.h>
20 #include <graphics/text.h>
21 #include <utility/tagitem.h>
22 #include <devices/inputevent.h>
23 #include <proto/alib.h>
24 #include <proto/utility.h>
26 #include <string.h> /* memset() */
30 #include <aros/debug.h>
32 #include "gadtools_intern.h"
34 /**********************************************************************************************/
36 #define GadToolsBase ((struct GadToolsBase_intern *)cl->cl_UserData)
38 /**********************************************************************************************/
40 #define TEXTF_CLIPPED (1 << 0)
41 #define TEXTF_BORDER (1 << 1)
42 #define TEXTF_COPYTEXT (1 << 2)
44 /**********************************************************************************************/
46 STATIC IPTR
text_set(Class
* cl
, Object
* o
, struct opSet
* msg
)
50 const struct TagItem
*tstate
;
51 struct TextData
*data
= INST_DATA(cl
, o
);
52 struct RastPort
*rport
;
54 EnterFunc(bug("Text::Set()\n"));
56 tstate
= msg
->ops_AttrList
;
58 while ((tag
= NextTagItem(&tstate
)))
60 IPTR tidata
= tag
->ti_Data
;
65 data
->gadgetkind
= (WORD
)tidata
;
69 data
->toprint
= tidata
;
70 D(bug("GTNM_Number: %ld\n", tidata
));
75 ((ULONG
*)REG_A7
)[0] = (ULONG
)o
;
76 ((ULONG
*)REG_A7
)[1] = data
->toprint
;
77 data
->toprint
= MyEmulHandle
->EmulCallDirect68k(data
->dispfunc
);
80 data
->toprint
= (ULONG
)data
->dispfunc((struct Gadget
*)o
,
88 /* If the user has GT_SetGadgetAttrs() us to a different text,
89 ** then don't copy it anymore
91 if (msg
->MethodID
!= OM_NEW
)
93 if (data
->flags
& TEXTF_COPYTEXT
)
95 FreeVec((APTR
)data
->toprint
);
96 data
->flags
&= ~TEXTF_COPYTEXT
;
98 data
->toprint
= tidata
;
99 D(bug("GTTX_Text: %s\n", tidata
));
104 case GTTX_Border
: /* [I] */
105 case GTNM_Border
: /* [I] */
107 data
->flags
|= TEXTF_BORDER
;
109 D(bug("Border: %d\n", tidata
));
113 /*case GTTX_FrontPen: [IS] */
114 case GTNM_FrontPen
: /* [IS] */
115 data
->frontpen
= (UBYTE
)tidata
;
116 D(bug("FrontPen: %d\n", tidata
));
120 /* case GTTX_BackPen: [IS] */
121 case GTNM_BackPen
: /* [IS] */
122 data
->backpen
= (UBYTE
)tidata
;
123 D(bug("BackPen: %d\n", tidata
));
127 /* case GTTX_Justification: [I] */
128 case GTNM_Justification
: /* [I] */
129 data
->justification
= (UBYTE
)tidata
;
130 D(bug("Justification: %d\n", tidata
));
133 case GTNM_Format
: /* [I] */
134 case GTA_Text_Format
:
135 data
->format
= (STRPTR
)tidata
;
136 D(bug("Format: %s\n", tidata
));
139 /* case GTTX_Clipped: [I] */
142 data
->flags
|= TEXTF_CLIPPED
;
143 D(bug("Clipped: %d\n", tidata
));
146 case GTNM_MaxNumberLen
: /* [I] */
147 data
->maxnumberlength
= tidata
;
148 D(bug("MaxNumberLen: %d\n", tidata
));
153 } /* while (iterate taglist) */
155 /* Redraw the gadget, if an attribute was changed and if this is the
156 objects' base-class. */
157 if ((retval
) && (OCLASS(o
) == cl
)) {
158 rport
= ObtainGIRPort(msg
->ops_GInfo
);
160 DoMethod(o
, GM_RENDER
, (IPTR
) msg
->ops_GInfo
, (IPTR
) rport
, GREDRAW_UPDATE
);
161 ReleaseGIRPort(rport
);
166 ReturnInt ("Text::Set", IPTR
, retval
);
169 /**********************************************************************************************/
171 IPTR
GTText__OM_GET(Class
* cl
, Object
* o
, struct opGet
*msg
)
173 struct TextData
*data
= INST_DATA(cl
, o
);
176 switch (msg
->opg_AttrID
)
179 case GTA_ChildGadgetKind
:
180 *(msg
->opg_Storage
) = data
->gadgetkind
;
185 retval
= DoSuperMethodA(cl
, o
, (Msg
)msg
);
192 /**********************************************************************************************/
194 IPTR
GTText__OM_NEW(Class
* cl
, Object
* o
, struct opSet
*msg
)
197 EnterFunc(bug("Text::New()\n"));
198 o
= (Object
*) DoSuperMethodA(cl
, o
, (Msg
)msg
);
201 struct TextData
*data
= INST_DATA(cl
, o
);
202 struct TextAttr
*tattr
, def_tattr
;
204 /* Set some defaults */
205 data
->format
= "%ld";
207 data
->frontpen
= TEXTPEN
;
208 data
->backpen
= BACKGROUNDPEN
;
209 data
->toprint
= (IPTR
) NULL
;
211 data
->maxnumberlength
= 0; /* This means "no limit" */
212 data
->dispfunc
= (APTR
)GetTagData(GTA_Text_DispFunc
, (IPTR
) NULL
, msg
->ops_AttrList
);
213 data
->labelplace
= GetTagData(GA_LabelPlace
, GV_LabelPlace_Left
, msg
->ops_AttrList
);
215 /* Open font to use for gadget */
217 /* We will *ALWAYS* have a valid DrawInfo struct */
218 data
->dri
= (struct DrawInfo
*)GetTagData(GA_DrawInfo
, (IPTR
) NULL
, msg
->ops_AttrList
);
220 def_tattr
.ta_Name
= data
->dri
->dri_Font
->tf_Message
.mn_Node
.ln_Name
;
221 def_tattr
.ta_YSize
= data
->dri
->dri_Font
->tf_YSize
;
222 def_tattr
.ta_Style
= 0;
223 def_tattr
.ta_Flags
= 0;
225 tattr
= (struct TextAttr
*)GetTagData(GA_TextAttr
, (IPTR
)&def_tattr
, msg
->ops_AttrList
);
227 data
->font
= OpenFont(tattr
);
232 if (GetTagData(GTTX_CopyText
, (IPTR
)FALSE
, msg
->ops_AttrList
))
236 D(bug("Got GTTX_CopyText\n"));
237 text
= (STRPTR
)GetTagData(GTTX_Text
, (IPTR
)"Text MUST be passed with OM_NEW", msg
->ops_AttrList
);
240 D(bug("Text: %s\n", text
));
241 /* Allocate copy buffer for the text */
242 data
->toprint
= (IPTR
)AllocVec(strlen(text
) + 1, MEMF_ANY
);
245 data
->flags
|= TEXTF_COPYTEXT
;
246 D(bug("Copying text\n"));
247 strcpy((STRPTR
)data
->toprint
, text
);
254 /* If text==NULL we have nothing to copy */
260 if ((text
= (STRPTR
)GetTagData(GTTX_Text
, (IPTR
) NULL
, msg
->ops_AttrList
)))
262 data
->toprint
= (IPTR
)text
;
266 D(bug("calling text_set\n"));
267 text_set(cl
, o
, msg
);
269 if (data
->flags
& TEXTF_BORDER
)
271 struct TagItem frame_tags
[] =
273 {IA_Width
, GetTagData(GA_Width
, 0, msg
->ops_AttrList
) },
274 {IA_Height
, GetTagData(GA_Height
, 0, msg
->ops_AttrList
) },
275 {IA_Resolution
, (data
->dri
->dri_Resolution
.X
<< 16) + data
->dri
->dri_Resolution
.Y
},
276 {IA_FrameType
, FRAME_BUTTON
},
277 {IA_Recessed
, TRUE
},
281 data
->frame
= NewObjectA(NULL
, FRAMEICLASS
, frame_tags
);
285 ReturnPtr ("Text::New", IPTR
, (IPTR
)o
);
288 CoerceMethod(cl
, o
, OM_DISPOSE
);
289 ReturnPtr ("Text::New", IPTR
, (IPTR
) NULL
);
292 /**********************************************************************************************/
297 AROS_UFH2 (void, puttostr
,
298 AROS_UFHA(UBYTE
, chr
, D0
),
299 AROS_UFHA(STRPTR
*,strPtrPtr
,A3
)
303 D(bug("Putting character %c into buffer at adress %p\n",
310 /**********************************************************************************************/
312 IPTR
GTText__GM_RENDER(Class
*cl
, struct Gadget
*g
, struct gpRender
*msg
)
314 UWORD
*pens
= msg
->gpr_GInfo
->gi_DrInfo
->dri_Pens
;
315 UBYTE textbuf
[256], *str
;
316 struct TextData
*data
= INST_DATA(cl
, g
);
317 WORD left
, left2
, top
, width
, height
, numchars
, tlength
;
318 struct TextFont
*oldfont
;
319 struct RastPort
*rp
= msg
->gpr_RPort
;
321 EnterFunc(bug("Text::Render()\n"));
328 if (msg
->gpr_Redraw
== GREDRAW_REDRAW
)
332 DrawImageState(msg
->gpr_RPort
,
333 (struct Image
*)data
->frame
,
337 msg
->gpr_GInfo
->gi_DrInfo
);
340 renderlabel(GadToolsBase
, g
, msg
->gpr_RPort
, data
->labelplace
);
343 if (data
->toprint
|| (data
->gadgetkind
!= TEXT_KIND
))
347 SetFont(rp
, data
->font
);
350 if (data
->gadgetkind
== TEXT_KIND
)
352 strncpy(str
, (char *)data
->toprint
, sizeof(textbuf
));
353 textbuf
[sizeof(textbuf
) - 1] = '\0';
355 else /* NUMERIC_KIND or label of SLIDER_KIND */
357 RawDoFmt(data
->format
, &(data
->toprint
), (VOID_FUNC
)AROS_ASMSYMNAME(puttostr
), &str
);
360 D(bug("Text formatted into: %s\n", textbuf
));
361 numchars
= strlen(textbuf
);
363 if (data
->flags
& TEXTF_BORDER
)
367 width
= g
->Width
- (VBORDER
+ 1) * 2;
368 height
= g
->Height
- (HBORDER
+ 1) * 2;
371 if (data
->flags
& TEXTF_CLIPPED
)
373 struct TextExtent te
;
375 /* See how many chars fits into the display area */
376 numchars
= TextFit(rp
, textbuf
, numchars
, &te
, NULL
, 1, width
, g
->Height
);
379 tlength
= TextLength(rp
, textbuf
, numchars
);
382 switch (data
->justification
)
387 left2
+= (width
- tlength
);
390 left2
+= ((width
- tlength
) / 2);
395 D(bug("Rendering text of lenghth %d at (%d, %d)\n", numchars
, left
, top
));
396 SetABPenDrMd(rp
, pens
[data
->backpen
], pens
[data
->backpen
], JAM2
);
397 RectFill(rp
, left
, top
, left
+ width
- 1, top
+ height
- 1);
398 SetAPen(rp
, pens
[data
->frontpen
]);
401 top
+ ((height
- data
->font
->tf_YSize
) / 2) + data
->font
->tf_Baseline
);
402 Text(rp
, textbuf
, numchars
);
404 SetFont(rp
, oldfont
);
406 } /* if (data->toprint || (data->gadgetkind != TEXT_KIND)) */
408 ReturnInt("Text::Render", IPTR
, 0);
411 /**********************************************************************************************/
413 IPTR
GTText__OM_DISPOSE(Class
*cl
, Object
*o
, Msg msg
)
415 struct TextData
*data
= INST_DATA(cl
, o
);
417 if (data
->flags
& TEXTF_COPYTEXT
) FreeVec((APTR
)data
->toprint
);
418 if (data
->font
) CloseFont(data
->font
);
419 if (data
->frame
) DisposeObject(data
->frame
);
421 return DoSuperMethodA(cl
, o
, msg
);
425 /**********************************************************************************************/
427 IPTR
GTText__OM_SET(Class
*cl
, Object
*o
, struct opSet
*msg
)
431 retval
= DoSuperMethodA(cl
, o
, (Msg
)msg
);
432 retval
+= text_set(cl
, o
, msg
);
434 /* If we have been subclassed, OM_UPDATE should not cause a GM_RENDER
435 * because it would circumvent the subclass from fully overriding it.
436 * The check of cl == OCLASS(o) should fail if we have been
437 * subclassed, and we have gotten here via DoSuperMethodA().
439 if ( retval
&& ( msg
->MethodID
== OM_UPDATE
) && ( cl
== OCLASS(o
) ) )
441 struct GadgetInfo
*gi
= msg
->ops_GInfo
;
444 struct RastPort
*rp
= ObtainGIRPort(gi
);
447 DoMethod(o
, GM_RENDER
, (IPTR
) gi
, (IPTR
) rp
, GREDRAW_REDRAW
);
456 /**********************************************************************************************/
458 IPTR
GTText__GM_GOACTIVE(Class
*cl
, Object
*o
, Msg msg
)
460 return (IPTR
)GMR_NOREUSE
;
463 /**********************************************************************************************/