Dtpic class updated:
[AROS.git] / workbench / libs / muimaster / classes / dtpic.c
blobaf3c80d4797d7576e59fdf80042a92917d2e7a25
1 /*
2 Copyright © 2002-2014, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 /* Dtpic.mui. Source based on the one from MUIUndoc */
8 #define MUIMASTER_YES_INLINE_STDARG
10 #include <stdio.h>
11 #include <stdlib.h>
13 #include <graphics/gfx.h>
14 #include <graphics/view.h>
15 #include <clib/alib_protos.h>
17 #include <datatypes/datatypesclass.h>
18 #include <datatypes/pictureclass.h>
19 #include <cybergraphx/cybergraphics.h>
21 #include <proto/exec.h>
22 #include <proto/graphics.h>
23 #include <proto/cybergraphics.h>
24 #include <proto/utility.h>
25 #include <proto/intuition.h>
26 #include <proto/muimaster.h>
27 #include <proto/datatypes.h>
29 #include <string.h>
31 /* #define MYDEBUG 1 */
32 #include "debug.h"
34 #include "mui.h"
35 #include "muimaster_intern.h"
36 #include "support.h"
37 #include "support_classes.h"
38 #include "dtpic_private.h"
40 extern struct Library *MUIMasterBase;
42 #ifdef DataTypesBase
43 #undef DataTypesBase
44 #endif
46 #define DataTypesBase data->datatypesbase
48 static void killdto(struct Dtpic_DATA *data)
50 data->bm = NULL;
51 data->bmhd = NULL;
53 if (data->dto)
55 DisposeDTObject(data->dto);
56 data->dto = NULL;
59 if (data->datatypesbase)
61 CloseLibrary(data->datatypesbase);
65 static void change_event_handler(Object *obj, struct Dtpic_DATA *data)
67 // enable only events which we really need
68 ULONG events = 0;
70 if (data->darkenselstate)
72 events |= IDCMP_MOUSEBUTTONS;
74 else
76 // disable pending selected state
77 data->selected = FALSE;
80 if (data->lightenonmouse)
82 // FIXME: change to IDCMP_MOUSEOBJECT if available
83 events |= IDCMP_MOUSEMOVE;
85 else
87 // disable highlighting mode
88 data->highlighted = FALSE;
91 if (data->deltaalpha)
93 events |= IDCMP_INTUITICKS;
96 if (events != data->ehn.ehn_Events)
98 // remove event handler if it was installed
99 if (data->eh_active)
101 DoMethod(_win(obj), MUIM_Window_RemEventHandler, &data->ehn);
103 // enable event handler for changed events
104 data->ehn.ehn_Events = events;
105 DoMethod(_win(obj), MUIM_Window_AddEventHandler, &data->ehn);
106 data->eh_active = TRUE;
110 static void update_alpha(struct Dtpic_DATA *data)
112 if (data->fade < 0)
114 // immediately set alpha to end value
115 data->currentalpha = data->alpha;
116 data->deltaalpha = 0;
118 else
120 // calculate delta
121 if (data->alpha > data->currentalpha)
123 data->deltaalpha = data->fade;
125 else if (data->alpha < data->currentalpha)
127 data->deltaalpha = -data->fade;
129 else
131 data->deltaalpha = 0;
134 bug("[Dtpic/update_alpha] alpha %d delta %d current %d\n", data->alpha, data->deltaalpha, data->currentalpha);
138 * We copy the filename, as the file is opened later in setup and
139 * not at once.
141 IPTR Dtpic__OM_NEW(struct IClass *cl, Object *obj, struct opSet *msg)
143 obj = (Object *) DoSuperMethodA(cl, obj, (Msg) msg);
145 if (obj)
147 struct Dtpic_DATA *data = INST_DATA(cl, obj);
148 struct TagItem *tags = msg->ops_AttrList;
149 struct TagItem *tag;
151 // initial values
152 data->currentalpha = data->alpha = 0xff;
154 while ((tag = NextTagItem(&tags)) != NULL)
156 switch (tag->ti_Tag)
158 case MUIA_Dtpic_Name:
159 // acc. to AOS4-MUI4 autodoc the string isn't copied
160 data->name = (STRPTR)tag->ti_Data;
161 break;
162 case MUIA_Dtpic_Alpha:
163 data->alpha = tag->ti_Data;
164 break;
165 case MUIA_Dtpic_DarkenSelState:
166 data->darkenselstate = tag->ti_Data ? TRUE : FALSE;
167 break;
168 case MUIA_Dtpic_Fade:
169 data->fade = tag->ti_Data;
170 break;
171 case MUIA_Dtpic_LightenOnMouse:
172 data->lightenonmouse = tag->ti_Data ? TRUE : FALSE;
173 break;
177 data->ehn.ehn_Events = 0;
178 data->ehn.ehn_Priority = 0;
179 data->ehn.ehn_Flags = 0;
180 data->ehn.ehn_Object = obj;
181 data->ehn.ehn_Class = cl;
183 update_alpha(data);
186 return (IPTR) obj;
189 IPTR setup_datatype(struct IClass *cl, Object *obj)
191 struct Dtpic_DATA *data = INST_DATA(cl, obj);
193 if (data->dto)
194 killdto(data); /* Object already existed */
196 if (data->name)
198 if ((data->datatypesbase = OpenLibrary("datatypes.library", 39)))
200 /* Prevent DOS Requesters from showing up */
202 struct Process *me = (struct Process *)FindTask(0);
203 APTR oldwinptr = me->pr_WindowPtr;
205 me->pr_WindowPtr = (APTR) - 1;
207 data->dto = NewDTObject(data->name, DTA_GroupID, GID_PICTURE,
208 OBP_Precision, PRECISION_IMAGE,
209 PDTA_Screen, _screen(obj),
210 PDTA_DestMode, PMODE_V43,
211 PDTA_UseFriendBitMap, TRUE, TAG_DONE);
212 me->pr_WindowPtr = oldwinptr;
214 if (data->dto)
216 struct FrameInfo fri = { 0 };
218 DoMethod(data->dto, DTM_FRAMEBOX, 0, &fri, &fri,
219 sizeof(struct FrameInfo), 0);
221 if (fri.fri_Dimensions.Depth > 0)
223 if (DoMethod(data->dto, DTM_PROCLAYOUT, 0, 1))
225 get(data->dto, PDTA_BitMapHeader, &data->bmhd);
227 if (data->bmhd)
229 if (data->bmhd->bmh_Masking != mskNone)
230 set(obj, MUIA_FillArea, TRUE);
231 else
232 set(obj, MUIA_FillArea, FALSE);
234 GetDTAttrs(data->dto, PDTA_DestBitMap,
235 &data->bm, TAG_DONE);
237 if (!data->bm)
239 GetDTAttrs(data->dto, PDTA_BitMap,
240 &data->bm, TAG_DONE);
243 if (data->bm)
244 return TRUE;
251 killdto(data);
253 return TRUE;
256 IPTR Dtpic__MUIM_Setup(struct IClass *cl, Object *obj,
257 struct MUIP_Setup *msg)
259 if (!DoSuperMethodA(cl, obj, (Msg) msg))
260 return FALSE;
262 return setup_datatype(cl, obj);
265 IPTR Dtpic__MUIM_Cleanup(struct IClass *cl, Object *obj,
266 struct MUIP_Cleanup *msg)
268 struct Dtpic_DATA *data = INST_DATA(cl, obj);
270 if (data->eh_active)
272 DoMethod(_win(obj), MUIM_Window_RemEventHandler, &data->ehn);
275 killdto(data);
277 return DoSuperMethodA(cl, obj, (Msg) msg);
280 IPTR Dtpic__MUIM_AskMinMax(struct IClass *cl, Object *obj,
281 struct MUIP_AskMinMax *msg)
283 struct Dtpic_DATA *data = INST_DATA(cl, obj);
284 IPTR retval;
286 retval = DoSuperMethodA(cl, obj, (Msg) msg);
288 if (data->bm)
290 msg->MinMaxInfo->MinWidth += data->bmhd->bmh_Width;
291 msg->MinMaxInfo->MinHeight += data->bmhd->bmh_Height;
292 msg->MinMaxInfo->DefWidth += data->bmhd->bmh_Width;
293 msg->MinMaxInfo->DefHeight += data->bmhd->bmh_Height;
294 msg->MinMaxInfo->MaxWidth += data->bmhd->bmh_Width;
295 msg->MinMaxInfo->MaxHeight += data->bmhd->bmh_Height;
298 return retval;
301 IPTR Dtpic__MUIM_Draw(struct IClass *cl, Object *obj,
302 struct MUIP_Draw *msg)
304 struct Dtpic_DATA *data = INST_DATA(cl, obj);
306 // TODO: rendering of different states
308 bug("[Dtpic/MUIM_Draw] selected %d highlighted %d alpha %d\n",
309 data->selected, data->highlighted, data->currentalpha);
311 DoSuperMethodA(cl, obj, (Msg) msg);
313 if ((msg->flags & MADF_DRAWOBJECT) && data->bm)
315 /* Note: codes taken from picture.datatype GM_RENDER routine */
316 ULONG depth = (ULONG) GetBitMapAttr(_rp(obj)->BitMap, BMA_DEPTH);
318 if ((depth >= 15) && (data->bmhd->bmh_Masking == mskHasAlpha))
320 /* Transparency on high color rast port with alpha channel in
321 * picture */
322 ULONG *img =
323 AllocVec(_mwidth(obj) * _mheight(obj) * 4, MEMF_ANY);
324 if (img)
326 struct pdtBlitPixelArray pa;
327 pa.MethodID = PDTM_READPIXELARRAY;
328 pa.pbpa_PixelData = (UBYTE *) img;
329 pa.pbpa_PixelFormat = PBPAFMT_ARGB;
330 pa.pbpa_PixelArrayMod = _mwidth(obj) * 4;
331 pa.pbpa_Left = 0;
332 pa.pbpa_Top = 0;
333 pa.pbpa_Width = _mwidth(obj);
334 pa.pbpa_Height = _mheight(obj);
335 if (DoMethodA(data->dto, (Msg) & pa))
336 WritePixelArrayAlpha(img, 0, 0, _mwidth(obj) * 4,
337 _rp(obj), _mleft(obj), _mtop(obj), _mwidth(obj),
338 _mheight(obj), 0xffffffff);
339 FreeVec((APTR) img);
342 else
344 if (data->bmhd->bmh_Masking == mskHasMask)
346 /* Transparency with mask */
347 APTR mask = NULL;
349 GetDTAttrs(data->dto, PDTA_MaskPlane, (IPTR) & mask,
350 TAG_DONE);
352 if (mask)
353 BltMaskBitMapRastPort(data->bm, 0, 0, _rp(obj),
354 _mleft(obj), _mtop(obj), _mwidth(obj),
355 _mheight(obj), 0xE0, (PLANEPTR) mask);
357 else
359 /* All other cases */
360 BltBitMapRastPort(data->bm, 0, 0, _rp(obj), _mleft(obj),
361 _mtop(obj), _mwidth(obj), _mheight(obj), 0xC0);
366 return 0;
369 IPTR Dtpic__OM_DISPOSE(struct IClass *cl, Object *obj, Msg msg)
371 //struct Dtpic_DATA *data = INST_DATA(cl, obj);
373 return DoSuperMethodA(cl, obj, msg);
376 IPTR Dtpic__OM_SET(struct IClass *cl, Object *obj, struct opSet *msg)
378 struct Dtpic_DATA *data = INST_DATA(cl, obj);
379 struct TagItem *tags = msg->ops_AttrList;
380 struct TagItem *tag;
381 ULONG needs_redraw = 0;
383 while ((tag = NextTagItem(&tags)) != NULL)
385 switch (tag->ti_Tag)
387 case MUIA_Dtpic_Name:
388 /* If no filename or different filenames */
389 if (!data->name || strcmp(data->name, (char *)tag->ti_Data))
391 data->name = (STRPTR)tag->ti_Data;
393 /* Run immediate setup only if base class is setup up */
394 if (_flags(obj) & MADF_SETUP)
395 setup_datatype(cl, obj);
396 needs_redraw = 1;
398 break;
399 case MUIA_Dtpic_Alpha:
400 data->alpha = tag->ti_Data;
401 break;
402 case MUIA_Dtpic_Fade:
403 data->fade = tag->ti_Data;
404 break;
408 update_alpha(data);
409 change_event_handler(obj, data);
411 if (needs_redraw)
413 MUI_Redraw(obj, MADF_DRAWOBJECT);
416 return DoSuperMethodA(cl, obj, (Msg) msg);
419 IPTR Dtpic__OM_GET(struct IClass *cl, Object *obj, struct opGet *msg)
421 struct Dtpic_DATA *data = INST_DATA(cl, obj);
423 switch (msg->opg_AttrID)
425 case MUIA_Dtpic_Name:
426 *(msg->opg_Storage) = (IPTR) data->name;
427 return TRUE;
428 case MUIA_Dtpic_Alpha:
429 *(msg->opg_Storage) = data->alpha;
430 return TRUE;
431 case MUIA_Dtpic_DarkenSelState:
432 *(msg->opg_Storage) = data->darkenselstate;
433 return TRUE;
434 case MUIA_Dtpic_Fade:
435 *(msg->opg_Storage) = data->fade;
436 return TRUE;
437 case MUIA_Dtpic_LightenOnMouse:
438 *(msg->opg_Storage) = data->lightenonmouse;
439 return TRUE;
442 return DoSuperMethodA(cl, obj, (Msg) msg);
445 IPTR Dtpic__MUIM_HandleEvent(struct IClass *cl, Object *obj,
446 struct MUIP_HandleEvent *msg)
448 struct Dtpic_DATA *data = INST_DATA(cl, obj);
450 if (msg->imsg)
452 switch (msg->imsg->Class)
454 case IDCMP_INTUITICKS:
455 data->currentalpha += data->deltaalpha;
456 if (data->deltaalpha > 0)
458 if (data->currentalpha > data->alpha)
460 // reached target alpha, no more incrementing
461 data->currentalpha = data->alpha;
462 data->deltaalpha = 0;
465 else if (data->deltaalpha < 0)
467 if (data->currentalpha < data->alpha)
469 // reached target alpha, no more decrementing
470 data->currentalpha = data->alpha;
471 data->deltaalpha = 0;
474 bug("intuitick %d %d\n", msg->imsg->MouseX, msg->imsg->MouseY);
475 update_alpha(data);
476 change_event_handler(obj, data);
477 MUI_Redraw(obj, MADF_DRAWUPDATE);
479 break;
481 case IDCMP_MOUSEBUTTONS:
482 if (msg->imsg->Code==SELECTDOWN)
484 if (_isinobject(obj, msg->imsg->MouseX, msg->imsg->MouseY))
486 data->selected = TRUE;
487 bug("selectdown %d %d\n", msg->imsg->MouseX, msg->imsg->MouseY);
488 MUI_Redraw(obj, MADF_DRAWUPDATE);
491 else if (msg->imsg->Code==SELECTUP)
493 if (_isinobject(obj, msg->imsg->MouseX, msg->imsg->MouseY))
495 data->selected = FALSE;
496 bug("selectup %d %d\n", msg->imsg->MouseX, msg->imsg->MouseY);
497 MUI_Redraw(obj, MADF_DRAWUPDATE);
500 break;
502 case IDCMP_MOUSEMOVE:
503 if (_isinobject(obj, msg->imsg->MouseX, msg->imsg->MouseY))
505 data->highlighted = TRUE;
506 bug("mouse move %d %d\n", msg->imsg->MouseX, msg->imsg->MouseY);
508 else
510 data->highlighted = FALSE;
512 MUI_Redraw(obj, MADF_DRAWUPDATE);
513 break;
517 return 0;
520 IPTR Dtpic__MUIM_Show(struct IClass *cl, Object *obj,
521 struct MUIP_Show *msg)
523 struct Dtpic_DATA *data = INST_DATA(cl, obj);
524 IPTR retval;
526 retval = DoSuperMethodA(cl, obj, (Msg) msg);
528 change_event_handler(obj, data);
530 return retval;
533 IPTR Dtpic__MUIM_Hide(struct IClass *cl, Object *obj,
534 struct MUIP_Hide *msg)
536 struct Dtpic_DATA *data = INST_DATA(cl, obj);
538 // remove event handler if it was installed
539 if (data->eh_active)
541 DoMethod(_win(obj), MUIM_Window_RemEventHandler, &data->ehn);
542 data->eh_active = FALSE;
545 return DoSuperMethodA(cl, obj, (Msg) msg);
549 #if ZUNE_BUILTIN_DTPIC
550 BOOPSI_DISPATCHER(IPTR, Dtpic_Dispatcher, cl, obj, msg)
552 switch (msg->MethodID)
554 case OM_NEW:
555 return Dtpic__OM_NEW(cl, obj, (APTR)msg);
556 case OM_DISPOSE:
557 return Dtpic__OM_DISPOSE(cl, obj, (APTR)msg);
558 case OM_SET:
559 return Dtpic__OM_SET(cl, obj, (APTR)msg);
560 case OM_GET:
561 return Dtpic__OM_GET(cl, obj, (APTR)msg);
563 case MUIM_Setup:
564 return Dtpic__MUIM_Setup(cl, obj, (APTR)msg);
565 case MUIM_Cleanup:
566 return Dtpic__MUIM_Cleanup(cl, obj, (APTR)msg);
568 case MUIM_Show:
569 return Dtpic__MUIM_Show(cl, obj, (APTR)msg);
570 case MUIM_Hide:
571 return Dtpic__MUIM_Show(cl, obj, (APTR)msg);
573 case MUIM_AskMinMax:
574 return Dtpic__MUIM_AskMinMax(cl, obj, (APTR)msg);
575 case MUIM_Draw:
576 return Dtpic__MUIM_Draw(cl, obj, (APTR)msg);
577 case MUIM_HandleEvent:
578 return Dtpic__MUIM_HandleEvent(cl, obj, (APTR)msg);
580 default:
581 return DoSuperMethodA(cl, obj, msg);
584 BOOPSI_DISPATCHER_END
586 const struct __MUIBuiltinClass _MUI_Dtpic_desc =
588 MUIC_Dtpic,
589 MUIC_Area,
590 sizeof(struct Dtpic_DATA),
591 (void *) Dtpic_Dispatcher
593 #endif /* ZUNE_BUILTIN_DTPIC */