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
)
49 struct TagItem
*tag
, *tstate
;
50 struct TextData
*data
= INST_DATA(cl
, o
);
51 struct RastPort
*rport
;
53 EnterFunc(bug("Text::Set()\n"));
55 tstate
= msg
->ops_AttrList
;
57 while ((tag
= NextTagItem(&tstate
)))
59 IPTR tidata
= tag
->ti_Data
;
64 data
->gadgetkind
= (WORD
)tidata
;
68 data
->toprint
= tidata
;
69 D(bug("GTNM_Number: %ld\n", tidata
));
74 g
= data
->parentgadget
? data
->parentgadget
: (struct Gadget
*)o
;
77 ((ULONG
*)REG_A7
)[0] = (ULONG
)g
;
78 ((ULONG
*)REG_A7
)[1] = data
->toprint
;
79 data
->toprint
= MyEmulHandle
->EmulCallDirect68k(data
->dispfunc
);
82 data
->toprint
= data
->dispfunc(g
, (WORD
)data
->toprint
);
89 /* If the user has GT_SetGadgetAttrs() us to a different text,
90 ** then don't copy it anymore
92 if (msg
->MethodID
!= OM_NEW
)
94 if (data
->flags
& TEXTF_COPYTEXT
)
96 FreeVec((APTR
)data
->toprint
);
97 data
->flags
&= ~TEXTF_COPYTEXT
;
99 data
->toprint
= tidata
;
100 D(bug("GTTX_Text: %s\n", tidata
));
105 case GTTX_Border
: /* [I] */
106 case GTNM_Border
: /* [I] */
108 data
->flags
|= TEXTF_BORDER
;
110 D(bug("Border: %d\n", tidata
));
114 /*case GTTX_FrontPen: [IS] */
115 case GTNM_FrontPen
: /* [IS] */
116 data
->frontpen
= (UBYTE
)tidata
;
117 D(bug("FrontPen: %d\n", tidata
));
121 /* case GTTX_BackPen: [IS] */
122 case GTNM_BackPen
: /* [IS] */
123 data
->backpen
= (UBYTE
)tidata
;
124 D(bug("BackPen: %d\n", tidata
));
128 /* case GTTX_Justification: [I] */
129 case GTNM_Justification
: /* [I] */
130 data
->justification
= (UBYTE
)tidata
;
131 D(bug("Justification: %d\n", tidata
));
134 case GTNM_Format
: /* [I] */
135 case GTA_Text_Format
:
136 data
->format
= (STRPTR
)tidata
;
137 D(bug("Format: %s\n", tidata
));
140 /* case GTTX_Clipped: [I] */
143 data
->flags
|= TEXTF_CLIPPED
;
144 D(bug("Clipped: %d\n", tidata
));
147 case GTNM_MaxNumberLen
: /* [I] */
148 data
->maxnumberlength
= tidata
;
149 D(bug("MaxNumberLen: %d\n", tidata
));
154 } /* while (iterate taglist) */
156 /* Redraw the gadget, if an attribute was changed and if this is the
157 objects' base-class. */
158 if ((retval
) && (OCLASS(o
) == cl
)) {
159 rport
= ObtainGIRPort(msg
->ops_GInfo
);
161 DoMethod(o
, GM_RENDER
, (IPTR
) msg
->ops_GInfo
, (IPTR
) rport
, GREDRAW_UPDATE
);
162 ReleaseGIRPort(rport
);
167 ReturnInt ("Text::Set", IPTR
, retval
);
170 /**********************************************************************************************/
172 IPTR
GTText__OM_GET(Class
* cl
, Object
* o
, struct opGet
*msg
)
174 struct TextData
*data
= INST_DATA(cl
, o
);
177 switch (msg
->opg_AttrID
)
180 case GTA_ChildGadgetKind
:
181 *(msg
->opg_Storage
) = data
->gadgetkind
;
186 retval
= DoSuperMethodA(cl
, o
, (Msg
)msg
);
193 /**********************************************************************************************/
195 IPTR
GTText__OM_NEW(Class
* cl
, Object
* o
, struct opSet
*msg
)
198 EnterFunc(bug("Text::New()\n"));
199 o
= (Object
*) DoSuperMethodA(cl
, o
, (Msg
)msg
);
202 struct TextData
*data
= INST_DATA(cl
, o
);
203 struct TextAttr
*tattr
, def_tattr
;
205 /* Set some defaults */
206 data
->format
= "%ld";
208 data
->frontpen
= TEXTPEN
;
209 data
->backpen
= BACKGROUNDPEN
;
210 data
->toprint
= (IPTR
) NULL
;
212 data
->maxnumberlength
= 0; /* This means "no limit" */
213 data
->dispfunc
= (APTR
)GetTagData(GTA_Text_DispFunc
, (IPTR
) NULL
, msg
->ops_AttrList
);
214 data
->labelplace
= GetTagData(GA_LabelPlace
, GV_LabelPlace_Left
, msg
->ops_AttrList
);
215 data
->parentgadget
= (struct Gadget
*)GetTagData(GTA_Text_ParentGadget
, 0, msg
->ops_AttrList
);
217 /* Open font to use for gadget */
219 /* We will *ALWAYS* have a valid DrawInfo struct */
220 data
->dri
= (struct DrawInfo
*)GetTagData(GA_DrawInfo
, (IPTR
) NULL
, msg
->ops_AttrList
);
222 def_tattr
.ta_Name
= data
->dri
->dri_Font
->tf_Message
.mn_Node
.ln_Name
;
223 def_tattr
.ta_YSize
= data
->dri
->dri_Font
->tf_YSize
;
224 def_tattr
.ta_Style
= 0;
225 def_tattr
.ta_Flags
= 0;
227 tattr
= (struct TextAttr
*)GetTagData(GA_TextAttr
, (IPTR
)&def_tattr
, msg
->ops_AttrList
);
229 data
->font
= OpenFont(tattr
);
234 if (GetTagData(GTTX_CopyText
, (IPTR
)FALSE
, msg
->ops_AttrList
))
238 D(bug("Got GTTX_CopyText\n"));
239 text
= (STRPTR
)GetTagData(GTTX_Text
, (IPTR
)"Text MUST be passed with OM_NEW", msg
->ops_AttrList
);
242 D(bug("Text: %s\n", text
));
243 /* Allocate copy buffer for the text */
244 data
->toprint
= (IPTR
)AllocVec(strlen(text
) + 1, MEMF_ANY
);
247 data
->flags
|= TEXTF_COPYTEXT
;
248 D(bug("Copying text\n"));
249 strcpy((STRPTR
)data
->toprint
, text
);
256 /* If text==NULL we have nothing to copy */
262 if ((text
= (STRPTR
)GetTagData(GTTX_Text
, (IPTR
) NULL
, msg
->ops_AttrList
)))
264 data
->toprint
= (IPTR
)text
;
268 D(bug("calling text_set\n"));
269 text_set(cl
, o
, msg
);
271 if (data
->flags
& TEXTF_BORDER
)
273 struct TagItem frame_tags
[] =
275 {IA_Width
, GetTagData(GA_Width
, 0, msg
->ops_AttrList
) },
276 {IA_Height
, GetTagData(GA_Height
, 0, msg
->ops_AttrList
) },
277 {IA_Resolution
, (data
->dri
->dri_Resolution
.X
<< 16) + data
->dri
->dri_Resolution
.Y
},
278 {IA_FrameType
, FRAME_BUTTON
},
279 {IA_Recessed
, TRUE
},
283 data
->frame
= NewObjectA(NULL
, FRAMEICLASS
, frame_tags
);
287 ReturnPtr ("Text::New", IPTR
, (IPTR
)o
);
290 CoerceMethod(cl
, o
, OM_DISPOSE
);
291 ReturnPtr ("Text::New", IPTR
, (IPTR
) NULL
);
294 /**********************************************************************************************/
299 AROS_UFH2 (void, puttostr
,
300 AROS_UFHA(UBYTE
, chr
, D0
),
301 AROS_UFHA(STRPTR
*,strPtrPtr
,A3
)
305 D(bug("Putting character %c into buffer at adress %p\n",
312 /**********************************************************************************************/
314 IPTR
GTText__GM_RENDER(Class
*cl
, struct Gadget
*g
, struct gpRender
*msg
)
316 UWORD
*pens
= msg
->gpr_GInfo
->gi_DrInfo
->dri_Pens
;
317 UBYTE textbuf
[256], *str
;
318 struct TextData
*data
= INST_DATA(cl
, g
);
319 WORD left
, left2
, top
, width
, height
, numchars
, tlength
;
320 struct TextFont
*oldfont
;
321 struct RastPort
*rp
= msg
->gpr_RPort
;
323 EnterFunc(bug("Text::Render()\n"));
330 if (msg
->gpr_Redraw
== GREDRAW_REDRAW
)
334 DrawImageState(msg
->gpr_RPort
,
335 (struct Image
*)data
->frame
,
339 msg
->gpr_GInfo
->gi_DrInfo
);
342 renderlabel(GadToolsBase
, g
, msg
->gpr_RPort
, data
->labelplace
);
345 if (data
->toprint
|| (data
->gadgetkind
!= TEXT_KIND
))
349 SetFont(rp
, data
->font
);
352 if (data
->gadgetkind
== TEXT_KIND
)
354 strncpy(str
, (char *)data
->toprint
, sizeof(textbuf
));
355 textbuf
[sizeof(textbuf
) - 1] = '\0';
357 else /* NUMERIC_KIND or label of SLIDER_KIND */
359 ULONG value
= data
->toprint
;
360 RawDoFmt(data
->format
, (RAWARG
)&value
, (VOID_FUNC
)AROS_ASMSYMNAME(puttostr
), &str
);
363 D(bug("Text formatted into: %s\n", textbuf
));
364 numchars
= strlen(textbuf
);
366 if (data
->flags
& TEXTF_BORDER
)
370 width
= g
->Width
- (VBORDER
+ 1) * 2;
371 height
= g
->Height
- (HBORDER
+ 1) * 2;
374 if (data
->flags
& TEXTF_CLIPPED
)
376 struct TextExtent te
;
378 /* See how many chars fits into the display area */
379 numchars
= TextFit(rp
, textbuf
, numchars
, &te
, NULL
, 1, width
, g
->Height
);
382 tlength
= TextLength(rp
, textbuf
, numchars
);
385 switch (data
->justification
)
390 left2
+= (width
- tlength
);
393 left2
+= ((width
- tlength
) / 2);
398 D(bug("Rendering text of lenghth %d at (%d, %d)\n", numchars
, left
, top
));
399 SetABPenDrMd(rp
, pens
[data
->backpen
], pens
[data
->backpen
], JAM2
);
400 RectFill(rp
, left
, top
, left
+ width
- 1, top
+ height
- 1);
401 SetAPen(rp
, pens
[data
->frontpen
]);
404 top
+ ((height
- data
->font
->tf_YSize
) / 2) + data
->font
->tf_Baseline
);
405 Text(rp
, textbuf
, numchars
);
407 SetFont(rp
, oldfont
);
409 } /* if (data->toprint || (data->gadgetkind != TEXT_KIND)) */
411 ReturnInt("Text::Render", IPTR
, 0);
414 /**********************************************************************************************/
416 IPTR
GTText__OM_DISPOSE(Class
*cl
, Object
*o
, Msg msg
)
418 struct TextData
*data
= INST_DATA(cl
, o
);
420 if (data
->flags
& TEXTF_COPYTEXT
) FreeVec((APTR
)data
->toprint
);
421 if (data
->font
) CloseFont(data
->font
);
422 if (data
->frame
) DisposeObject(data
->frame
);
424 return DoSuperMethodA(cl
, o
, msg
);
428 /**********************************************************************************************/
430 IPTR
GTText__OM_SET(Class
*cl
, Object
*o
, struct opSet
*msg
)
434 retval
= DoSuperMethodA(cl
, o
, (Msg
)msg
);
435 retval
+= text_set(cl
, o
, msg
);
437 /* If we have been subclassed, OM_UPDATE should not cause a GM_RENDER
438 * because it would circumvent the subclass from fully overriding it.
439 * The check of cl == OCLASS(o) should fail if we have been
440 * subclassed, and we have gotten here via DoSuperMethodA().
442 if ( retval
&& ( msg
->MethodID
== OM_UPDATE
) && ( cl
== OCLASS(o
) ) )
444 struct GadgetInfo
*gi
= msg
->ops_GInfo
;
447 struct RastPort
*rp
= ObtainGIRPort(gi
);
450 DoMethod(o
, GM_RENDER
, (IPTR
) gi
, (IPTR
) rp
, GREDRAW_REDRAW
);
459 /**********************************************************************************************/
461 IPTR
GTText__GM_GOACTIVE(Class
*cl
, Object
*o
, Msg msg
)
463 return (IPTR
)GMR_NOREUSE
;
466 /**********************************************************************************************/