Tabs to spaces, more consistent formatting.
[AROS.git] / workbench / libs / muimaster / classes / text.c
blobc65a7acf0f345998187cff820406052f1c40ff60
1 /*
2 Copyright 1999, David Le Corfec.
3 Copyright 2002-2006, The AROS Development Team.
4 All rights reserved.
6 $Id$
7 */
9 #include <string.h>
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <exec/types.h>
14 #include <clib/alib_protos.h>
15 #include <proto/exec.h>
16 #include <proto/intuition.h>
17 #include <proto/graphics.h>
18 #include <proto/utility.h>
19 #include <proto/dos.h>
20 #include <proto/muimaster.h>
22 #include "mui.h"
23 #include "muimaster_intern.h"
24 #include "support.h"
25 #include "textengine.h"
27 extern struct Library *MUIMasterBase;
29 //#define MYDEBUG 1
30 #include "debug.h"
33 struct MUI_TextData
35 ULONG mtd_Flags;
36 STRPTR contents;
37 CONST_STRPTR preparse;
38 TEXT hichar;
39 ZText *ztext;
40 LONG xpixel; /* needed for cursor up/down movements, can be -1 */
41 LONG xpos;
42 LONG ypos;
43 struct MUI_EventHandlerNode ehn;
45 LONG update; /* type of update: 1 - everything,
46 * 2 - insert char, no scroll */
47 LONG update_arg1;
48 LONG update_arg2;
51 #define MTDF_SETMIN (1<<0)
52 #define MTDF_SETMAX (1<<1)
53 #define MTDF_SETVMAX (1<<2)
54 #define MTDF_HICHAR (1<<3)
55 #define MTDF_HICHARIDX (1<<4)
56 #if 0
57 #define MTDF_EDITABLE (1<<5)
58 #define MTDF_MULTILINE (1<<6)
59 #endif
60 #define MTDF_ADVANCEONCR (1<<7)
62 static const int __version = 1;
63 static const int __revision = 1;
65 static void setup_text(struct MUI_TextData *data, Object *obj);
67 /**************************************************************************
68 OM_NEW
69 **************************************************************************/
70 IPTR Text__OM_NEW(struct IClass *cl, Object *obj, struct opSet *msg)
72 struct MUI_TextData *data;
73 struct TagItem *tags, *tag;
75 obj = (Object *) DoSuperMethodA(cl, obj, (Msg) msg);
76 if (!obj)
77 return FALSE;
79 data = INST_DATA(cl, obj);
80 data->mtd_Flags = MTDF_SETMIN | MTDF_SETVMAX;
82 /* parse initial taglist */
84 for (tags = msg->ops_AttrList; (tag = NextTagItem(&tags));)
86 switch (tag->ti_Tag)
88 case MUIA_Text_Contents:
89 if (tag->ti_Data)
90 data->contents = StrDup((STRPTR) tag->ti_Data);
91 break;
93 case MUIA_Text_HiChar:
94 data->hichar = tag->ti_Data;
95 _handle_bool_tag(data->mtd_Flags, tag->ti_Data, MTDF_HICHAR);
96 break;
98 case MUIA_Text_HiCharIdx:
99 data->hichar = tag->ti_Data;
100 _handle_bool_tag(data->mtd_Flags, tag->ti_Data, MTDF_HICHARIDX);
101 break;
103 case MUIA_Text_PreParse:
104 data->preparse = StrDup((STRPTR) tag->ti_Data);
105 break;
107 case MUIA_Text_SetMin:
108 _handle_bool_tag(data->mtd_Flags, tag->ti_Data, MTDF_SETMIN);
109 break;
111 case MUIA_Text_SetMax:
112 _handle_bool_tag(data->mtd_Flags, tag->ti_Data, MTDF_SETMAX);
113 break;
115 case MUIA_Text_SetVMax:
116 _handle_bool_tag(data->mtd_Flags, tag->ti_Data, MTDF_SETVMAX);
117 break;
119 #if 0
120 case MUIA_Text_Editable:
121 _handle_bool_tag(data->mtd_Flags, tag->ti_Data, MTDF_EDITABLE);
122 break;
124 case MUIA_Text_Multiline:
125 _handle_bool_tag(data->mtd_Flags, tag->ti_Data, MTDF_MULTILINE);
126 break;
127 #endif
131 if (!data->preparse)
132 data->preparse = StrDup("");
133 if (!data->contents)
134 data->contents = StrDup("");
136 if (!data->contents || !data->preparse)
138 CoerceMethod(cl, obj, OM_DISPOSE);
139 return (IPTR) NULL;
142 /* D(bug("Text_New(0x%lx)\n", obj)); */
144 data->ehn.ehn_Events = IDCMP_MOUSEBUTTONS;
145 data->ehn.ehn_Priority = 0;
146 data->ehn.ehn_Flags = 0;
147 data->ehn.ehn_Object = obj;
148 data->ehn.ehn_Class = cl;
150 data->xpixel = -1;
152 return (IPTR) obj;
155 /**************************************************************************
156 OM_DISPOSE
157 **************************************************************************/
158 IPTR Text__OM_DISPOSE(struct IClass *cl, Object *obj, Msg msg)
160 struct MUI_TextData *data = INST_DATA(cl, obj);
162 FreeVec(data->contents);
163 FreeVec((APTR) data->preparse);
165 return DoSuperMethodA(cl, obj, msg);
168 /**************************************************************************
169 OM_SET
170 **************************************************************************/
171 IPTR Text__OM_SET(struct IClass *cl, Object *obj, struct opSet *msg)
173 struct MUI_TextData *data = INST_DATA(cl, obj);
174 struct TagItem *tags = msg->ops_AttrList;
175 struct TagItem *tag;
177 while ((tag = NextTagItem(&tags)) != NULL)
179 switch (tag->ti_Tag)
181 case MUIA_Text_Contents:
183 char *new_contents =
184 StrDup(((char *)tag->ti_Data) ? (char *)tag->
185 ti_Data : "");
186 if (new_contents)
188 if (data->ztext)
190 zune_text_destroy(data->ztext);
191 data->ztext = NULL;
193 FreeVec(data->contents);
194 data->contents = new_contents;
195 if (_flags(obj) & MADF_SETUP)
196 setup_text(data, obj);
197 MUI_Redraw(obj, MADF_DRAWOBJECT); /* should be optimized */
200 break;
202 case MUIA_Text_PreParse:
204 char *new_preparse =
205 StrDup(((char *)tag->ti_Data) ? (char *)tag->
206 ti_Data : "");
207 if (new_preparse)
209 if (data->ztext)
211 zune_text_destroy(data->ztext);
212 data->ztext = NULL;
214 FreeVec((APTR) data->preparse);
215 data->preparse = new_preparse;
216 if (_flags(obj) & MADF_SETUP)
217 setup_text(data, obj);
218 MUI_Redraw(obj, MADF_DRAWOBJECT); /* should be optimized */
221 break;
223 case MUIA_Selected:
224 D(bug("Text_Set(%p) : MUIA_Selected val=%ld sss=%d\n", obj,
225 tag->ti_Data, ! !(_flags(obj) & MADF_SHOWSELSTATE)));
226 break;
230 return DoSuperMethodA(cl, obj, (Msg) msg);
234 /**************************************************************************
235 OM_GET
236 **************************************************************************/
237 IPTR Text__OM_GET(struct IClass *cl, Object *obj, struct opGet *msg)
239 struct MUI_TextData *data = INST_DATA(cl, obj);
241 #define STORE *(msg->opg_Storage)
242 switch (msg->opg_AttrID)
244 case MUIA_Text_Contents:
245 STORE = (IPTR) data->contents;
246 return TRUE;
248 case MUIA_Text_PreParse:
249 STORE = (IPTR) data->preparse;
250 return TRUE;
252 case MUIA_Version:
253 STORE = __version;
254 return TRUE;
256 case MUIA_Revision:
257 STORE = __revision;
258 return TRUE;
260 return DoSuperMethodA(cl, obj, (Msg) msg);
261 #undef STORE
264 /**************************************************************************
266 **************************************************************************/
267 static void setup_text(struct MUI_TextData *data, Object *obj)
269 if (data->mtd_Flags & MTDF_HICHAR)
271 data->ztext = zune_text_new(data->preparse, data->contents,
272 ZTEXT_ARG_HICHAR, data->hichar);
274 else if (data->mtd_Flags & MTDF_HICHARIDX)
276 data->ztext = zune_text_new(data->preparse, data->contents,
277 ZTEXT_ARG_HICHARIDX, data->hichar);
279 else
281 data->ztext = zune_text_new(data->preparse, data->contents,
282 ZTEXT_ARG_NONE, 0);
284 zune_text_get_bounds(data->ztext, obj);
286 /* D(bug("muimaster.library/text.c: ZText of 0x%lx at 0x%lx\n", */
287 /* obj, data->ztext)); */
290 /**************************************************************************
291 MUIM_Setup
292 **************************************************************************/
293 IPTR Text__MUIM_Setup(struct IClass *cl, Object *obj,
294 struct MUIP_Setup *msg)
296 struct MUI_TextData *data = INST_DATA(cl, obj);
298 if (!(DoSuperMethodA(cl, obj, (Msg) msg)))
299 return FALSE;
301 setup_text(data, obj);
303 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR) & data->ehn);
304 return TRUE;
307 /**************************************************************************
308 MUIM_Cleanup
309 **************************************************************************/
310 IPTR Text__MUIM_Cleanup(struct IClass *cl, Object *obj,
311 struct MUIP_Cleanup *msg)
313 struct MUI_TextData *data = INST_DATA(cl, obj);
315 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR) & data->ehn);
317 if (data->ztext)
319 zune_text_destroy(data->ztext);
320 data->ztext = NULL;
323 return (DoSuperMethodA(cl, obj, (Msg) msg));
326 /**************************************************************************
327 MUIM_Show
328 **************************************************************************/
329 IPTR Text__MUIM_Show(struct IClass *cl, Object *obj,
330 struct MUIP_Show *msg)
332 //struct MUI_TextData *data = INST_DATA(cl, obj);
334 if (!(DoSuperMethodA(cl, obj, (Msg) msg)))
335 return FALSE;
337 return TRUE;
340 /**************************************************************************
341 MUIM_Hide
342 **************************************************************************/
343 IPTR Text__MUIM_Hide(struct IClass *cl, Object *obj,
344 struct MUIP_Hide *msg)
346 //struct MUI_TextData *data = INST_DATA(cl, obj);
347 return DoSuperMethodA(cl, obj, (Msg) msg);
350 /**************************************************************************
351 MUIM_AskMinMax
352 **************************************************************************/
353 IPTR Text__MUIM_AskMinMax(struct IClass *cl, Object *obj,
354 struct MUIP_AskMinMax *msg)
356 int height;
357 struct MUI_TextData *data = INST_DATA(cl, obj);
359 DoSuperMethodA(cl, obj, (Msg) msg);
361 height = data->ztext->height;
362 if (_font(obj)->tf_YSize > height)
363 height = _font(obj)->tf_YSize;
364 /* D(bug("YSize=%ld\n", _font(obj)->tf_YSize)); */
366 #if 0
367 if (!(data->mtd_Flags & MTDF_EDITABLE))
368 #endif
370 msg->MinMaxInfo->MinWidth += data->ztext->width;
371 msg->MinMaxInfo->DefWidth += data->ztext->width;
372 msg->MinMaxInfo->MaxWidth += data->ztext->width;
374 #if 0
375 else
377 msg->MinMaxInfo->MinWidth += _font(obj)->tf_XSize * 4;
378 msg->MinMaxInfo->DefWidth += _font(obj)->tf_XSize * 12;
379 msg->MinMaxInfo->MaxWidth += MUI_MAXMAX;
381 #endif
383 #if 0
384 if (!(data->mtd_Flags & MTDF_MULTILINE))
385 #endif
387 msg->MinMaxInfo->MinHeight += height;
388 msg->MinMaxInfo->DefHeight += height;
389 if (!(data->mtd_Flags & MTDF_SETVMAX))
390 msg->MinMaxInfo->MaxHeight += MUI_MAXMAX;
391 else
392 msg->MinMaxInfo->MaxHeight += height;
394 #if 0
395 else
397 msg->MinMaxInfo->MinHeight += _font(obj)->tf_YSize;
398 msg->MinMaxInfo->DefHeight += _font(obj)->tf_YSize * 10;
399 msg->MinMaxInfo->MaxHeight += MUI_MAXMAX;
401 #endif
403 if (!(data->mtd_Flags & MTDF_SETMAX))
404 msg->MinMaxInfo->MaxWidth = MUI_MAXMAX;
406 if (!(data->mtd_Flags & MTDF_SETMIN))
407 msg->MinMaxInfo->MinWidth = 0;
409 D(bug
410 ("Text_AskMinMax 0x%lx (%s): Min=%ldx%ld Max=%ldx%ld Def=%ldx%ld\n",
411 obj, data->contents, msg->MinMaxInfo->MinWidth,
412 msg->MinMaxInfo->MinHeight, msg->MinMaxInfo->MaxWidth,
413 msg->MinMaxInfo->MaxHeight, msg->MinMaxInfo->DefWidth,
414 msg->MinMaxInfo->DefHeight));
416 return TRUE;
419 /**************************************************************************
420 MUIM_Draw
421 **************************************************************************/
422 IPTR Text__MUIM_Draw(struct IClass *cl, Object *obj,
423 struct MUIP_Draw *msg)
425 struct MUI_TextData *data = INST_DATA(cl, obj);
426 Object *act = NULL;
427 APTR clip;
429 /* D(bug("muimaster.library/text.c: Draw Text Object at " */
430 /* "0x%lx %ldx%ldx%ldx%ld\n", obj, _left(obj), _top(obj), */
431 /* _right(obj), _bottom(obj))); */
433 DoSuperMethodA(cl, obj, (Msg) msg);
435 if ((msg->flags & MADF_DRAWUPDATE) && !data->update)
436 return 0;
438 if (!(msg->flags & MADF_DRAWUPDATE))
439 data->update = 0;
441 if (msg->flags & MADF_DRAWUPDATE && data->update == 1)
443 DoMethod(obj, MUIM_DrawBackground, _mleft(obj), _mtop(obj),
444 _mwidth(obj), _mheight(obj), _mleft(obj), _mtop(obj), 0);
447 clip = MUI_AddClipping(muiRenderInfo(obj), _mleft(obj), _mtop(obj),
448 _mwidth(obj), _mheight(obj));
450 SetAPen(_rp(obj), _pens(obj)[MPEN_TEXT]);
453 get(_win(obj), MUIA_Window_ActiveObject, &act);
455 int y = (_mheight(obj) - data->ztext->height) / 2;
456 zune_text_draw(data->ztext, obj,
457 _mleft(obj), _mright(obj), _mtop(obj) + y);
461 MUI_RemoveClipping(muiRenderInfo(obj), clip);
462 data->update = 0;
463 return TRUE;
466 /**************************************************************************
467 MUIM_Export : to export an objects "contents" to a dataspace object.
468 **************************************************************************/
469 IPTR Text__MUIM_Export(struct IClass *cl, Object *obj,
470 struct MUIP_Export *msg)
472 //struct MUI_TextData *data = INST_DATA(cl, obj);
473 //STRPTR id;
475 #if 0
476 if ((id = muiNotifyData(obj)->mnd_ObjectID))
478 DoMethod(msg->dataspace, MUIM_Dataspace_AddString,
479 _U(id), _U("contents"), _U(data->contents));
481 #endif
482 return 0;
486 /**************************************************************************
487 MUIM_Import : to import an objects "contents" from a dataspace object.
488 **************************************************************************/
489 IPTR Text__MUIM_Import(struct IClass *cl, Object *obj,
490 struct MUIP_Import *msg)
492 //STRPTR id;
493 //STRPTR s;
495 #if 0
496 if ((id = muiNotifyData(obj)->mnd_ObjectID))
498 if ((s = (STRPTR) DoMethod(msg->dataspace,
499 MUIM_Dataspace_FindString, _U(id), _U("contents"))))
501 set(obj, MUIA_Text_Contents, _U(s));
504 #endif
505 return 0;
509 BOOPSI_DISPATCHER(IPTR, Text_Dispatcher, cl, obj, msg)
511 switch (msg->MethodID)
513 case OM_NEW:
514 return Text__OM_NEW(cl, obj, (struct opSet *)msg);
515 case OM_DISPOSE:
516 return Text__OM_DISPOSE(cl, obj, msg);
517 case OM_SET:
518 return Text__OM_SET(cl, obj, (struct opSet *)msg);
519 case OM_GET:
520 return Text__OM_GET(cl, obj, (struct opGet *)msg);
522 case MUIM_AskMinMax:
523 return Text__MUIM_AskMinMax(cl, obj, (APTR) msg);
524 case MUIM_Draw:
525 return Text__MUIM_Draw(cl, obj, (APTR) msg);
526 case MUIM_Setup:
527 return Text__MUIM_Setup(cl, obj, (APTR) msg);
528 case MUIM_Cleanup:
529 return Text__MUIM_Cleanup(cl, obj, (APTR) msg);
530 case MUIM_Show:
531 return Text__MUIM_Show(cl, obj, (APTR) msg);
532 case MUIM_Hide:
533 return Text__MUIM_Hide(cl, obj, (APTR) msg);
534 case MUIM_Export:
535 return Text__MUIM_Export(cl, obj, (APTR) msg);
536 case MUIM_Import:
537 return Text__MUIM_Import(cl, obj, (APTR) msg);
540 return DoSuperMethodA(cl, obj, msg);
542 BOOPSI_DISPATCHER_END
545 * Class descriptor.
547 const struct __MUIBuiltinClass _MUI_Text_desc =
549 MUIC_Text,
550 MUIC_Area,
551 sizeof(struct MUI_TextData),
552 (void *) Text_Dispatcher