revert between 56095 -> 55830 in arch
[AROS.git] / workbench / libs / muimaster / classes / dtpic.c
blob0d3799c21fadb816a2eef955cfd19bf132941777
1 /*
2 Copyright © 2002-2015, 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 if (data->bm_selected) FreeBitMap(data->bm_selected);
51 if (data->bm_highlighted) FreeBitMap(data->bm_highlighted);
52 data->bm = NULL;
53 data->bmhd = NULL;
54 data->bm_selected = NULL;
55 data->bm_highlighted = NULL;
57 if (data->dto)
59 DisposeDTObject(data->dto);
60 data->dto = NULL;
63 if (data->datatypesbase)
65 CloseLibrary(data->datatypesbase);
69 static void change_event_handler(Object *obj, struct Dtpic_DATA *data)
71 // enable only events which we really need
72 ULONG events = 0;
74 if (data->darkenselstate)
76 events |= IDCMP_MOUSEBUTTONS;
78 else
80 // disable pending selected state
81 data->selected = FALSE;
84 if (data->lightenonmouse)
86 // FIXME: change to IDCMP_MOUSEOBJECT if available
87 events |= IDCMP_MOUSEMOVE;
89 else
91 // disable highlighting mode
92 data->highlighted = FALSE;
95 if (data->deltaalpha)
97 events |= IDCMP_INTUITICKS;
100 if (events != data->ehn.ehn_Events)
102 // remove event handler if it was installed
103 if (data->eh_active)
105 DoMethod(_win(obj), MUIM_Window_RemEventHandler, &data->ehn);
107 // enable event handler for changed events
108 data->ehn.ehn_Events = events;
109 DoMethod(_win(obj), MUIM_Window_AddEventHandler, &data->ehn);
110 data->eh_active = TRUE;
114 static void update_alpha(struct Dtpic_DATA *data)
116 if (data->fade < 0)
118 // immediately set alpha to end value
119 data->currentalpha = data->alpha;
120 data->deltaalpha = 0;
122 else
124 // calculate delta
125 if (data->alpha > data->currentalpha)
127 // fading should happen every 1/20 sec.
128 // Because we're using Intuiticks we must
129 // convert the value.
130 data->deltaalpha = data->fade * 50 / 20;
132 else if (data->alpha < data->currentalpha)
134 data->deltaalpha = -data->fade * 50 / 20;
136 else
138 data->deltaalpha = 0;
141 D(bug("[Dtpic/update_alpha] alpha %d delta %d current %d\n",
142 data->alpha, data->deltaalpha, data->currentalpha));
145 static struct BitMap *clone_bitmap(struct BitMap *from_bm, ULONG operation,
146 ULONG value)
148 if (from_bm == NULL)
149 return NULL;
151 struct BitMap *to_bm = NULL;
152 struct RastPort rp;
154 UWORD width = GetBitMapAttr(from_bm, BMA_WIDTH);
155 UWORD height = GetBitMapAttr(from_bm, BMA_HEIGHT);
156 UWORD depth = GetBitMapAttr(from_bm, BMA_DEPTH);
158 InitRastPort(&rp);
159 to_bm = AllocBitMap(width, height, depth, BMF_MINPLANES, from_bm);
160 D(bug("[clone_bitmap] %p width %d height %d depth %d\n", to_bm, width,
161 height, depth));
162 if (to_bm)
164 rp.BitMap = to_bm;
165 BltBitMapRastPort(from_bm, 0, 0, &rp, 0, 0, width, height, 0xC0);
166 ProcessPixelArray(&rp, 0, 0, width, height, operation, value, NULL);
168 return to_bm;
171 IPTR setup_datatype(struct IClass *cl, Object *obj)
173 struct Dtpic_DATA *data = INST_DATA(cl, obj);
175 if (data->dto)
176 killdto(data); /* Object already existed */
178 if (data->name)
180 if ((data->datatypesbase = OpenLibrary("datatypes.library", 39)))
182 /* Prevent DOS Requesters from showing up */
184 struct Process *me = (struct Process *)FindTask(0);
185 APTR oldwinptr = me->pr_WindowPtr;
187 me->pr_WindowPtr = (APTR) - 1;
189 data->dto = NewDTObject(data->name, DTA_GroupID, GID_PICTURE,
190 OBP_Precision, PRECISION_IMAGE,
191 PDTA_Screen, _screen(obj),
192 PDTA_DestMode, PMODE_V43,
193 PDTA_UseFriendBitMap, TRUE, TAG_DONE);
194 me->pr_WindowPtr = oldwinptr;
196 if (data->dto)
198 struct FrameInfo fri = { 0 };
200 DoMethod(data->dto, DTM_FRAMEBOX, 0, &fri, &fri,
201 sizeof(struct FrameInfo), 0);
203 if (fri.fri_Dimensions.Depth > 0)
205 if (DoMethod(data->dto, DTM_PROCLAYOUT, 0, 1))
207 get(data->dto, PDTA_BitMapHeader, &data->bmhd);
209 if (data->bmhd)
211 if (data->bmhd->bmh_Masking != mskNone)
212 set(obj, MUIA_FillArea, TRUE);
213 else
214 set(obj, MUIA_FillArea, FALSE);
216 GetDTAttrs(data->dto, PDTA_DestBitMap,
217 &data->bm, TAG_DONE);
219 if (!data->bm)
221 GetDTAttrs(data->dto, PDTA_BitMap,
222 &data->bm, TAG_DONE);
225 if (data->bm)
227 /* create BitMaps for selected and
228 * highlighted state */
229 data->bm_selected =
230 clone_bitmap(data->bm, POP_DARKEN, 127);
231 data->bm_highlighted =
232 clone_bitmap(data->bm, POP_BRIGHTEN, 50);
234 return TRUE;
242 killdto(data);
244 return TRUE;
247 IPTR Dtpic__OM_NEW(struct IClass *cl, Object *obj, struct opSet *msg)
249 obj = (Object *) DoSuperMethodA(cl, obj, (Msg) msg);
251 if (obj)
253 struct Dtpic_DATA *data = INST_DATA(cl, obj);
254 struct TagItem *tags = msg->ops_AttrList;
255 struct TagItem *tag;
257 // initial values
258 data->currentalpha = data->alpha = 0xff;
260 while ((tag = NextTagItem(&tags)) != NULL)
262 switch (tag->ti_Tag)
264 case MUIA_Dtpic_Name:
265 // acc. to AOS4-MUI4 autodoc the string isn't copied
266 data->name = (STRPTR)tag->ti_Data;
267 break;
268 case MUIA_Dtpic_Alpha:
269 data->alpha = tag->ti_Data;
270 break;
271 case MUIA_Dtpic_DarkenSelState:
272 data->darkenselstate = tag->ti_Data ? TRUE : FALSE;
273 break;
274 case MUIA_Dtpic_Fade:
275 data->fade = tag->ti_Data;
276 break;
277 case MUIA_Dtpic_LightenOnMouse:
278 data->lightenonmouse = tag->ti_Data ? TRUE : FALSE;
279 break;
283 data->ehn.ehn_Events = 0;
284 data->ehn.ehn_Priority = 0;
285 data->ehn.ehn_Flags = 0;
286 data->ehn.ehn_Object = obj;
287 data->ehn.ehn_Class = cl;
289 update_alpha(data);
292 return (IPTR) obj;
295 IPTR Dtpic__MUIM_Setup(struct IClass *cl, Object *obj,
296 struct MUIP_Setup *msg)
298 if (!DoSuperMethodA(cl, obj, (Msg) msg))
299 return FALSE;
301 return setup_datatype(cl, obj);
304 IPTR Dtpic__MUIM_Cleanup(struct IClass *cl, Object *obj,
305 struct MUIP_Cleanup *msg)
307 struct Dtpic_DATA *data = INST_DATA(cl, obj);
309 if (data->eh_active)
311 DoMethod(_win(obj), MUIM_Window_RemEventHandler, &data->ehn);
314 killdto(data);
316 return DoSuperMethodA(cl, obj, (Msg) msg);
319 IPTR Dtpic__MUIM_AskMinMax(struct IClass *cl, Object *obj,
320 struct MUIP_AskMinMax *msg)
322 struct Dtpic_DATA *data = INST_DATA(cl, obj);
323 IPTR retval;
325 retval = DoSuperMethodA(cl, obj, (Msg) msg);
327 if (data->bm)
329 msg->MinMaxInfo->MinWidth += data->bmhd->bmh_Width;
330 msg->MinMaxInfo->MinHeight += data->bmhd->bmh_Height;
331 msg->MinMaxInfo->DefWidth += data->bmhd->bmh_Width;
332 msg->MinMaxInfo->DefHeight += data->bmhd->bmh_Height;
333 msg->MinMaxInfo->MaxWidth += data->bmhd->bmh_Width;
334 msg->MinMaxInfo->MaxHeight += data->bmhd->bmh_Height;
337 return retval;
340 IPTR Dtpic__MUIM_Draw(struct IClass *cl, Object *obj,
341 struct MUIP_Draw *msg)
343 struct Dtpic_DATA *data = INST_DATA(cl, obj);
345 // TODO: rendering of different states
347 D(bug("[Dtpic/MUIM_Draw] selected %d highlighted %d alpha %d\n",
348 data->selected, data->highlighted, data->currentalpha));
350 DoSuperMethodA(cl, obj, (Msg) msg);
352 if ((msg->flags & (MADF_DRAWOBJECT | MADF_DRAWUPDATE)) && data->bm)
354 /* Note: codes taken from picture.datatype GM_RENDER routine */
355 ULONG depth = (ULONG) GetBitMapAttr(_rp(obj)->BitMap, BMA_DEPTH);
357 if ((depth >= 15) && (data->bmhd->bmh_Masking == mskHasAlpha))
359 /* Transparency on high color rast port with alpha channel in
360 * picture */
361 ULONG *img =
362 AllocVec(_mwidth(obj) * _mheight(obj) * 4, MEMF_ANY);
363 if (img)
365 struct pdtBlitPixelArray pa;
366 pa.MethodID = PDTM_READPIXELARRAY;
367 pa.pbpa_PixelData = (UBYTE *) img;
368 pa.pbpa_PixelFormat = PBPAFMT_ARGB;
369 pa.pbpa_PixelArrayMod = _mwidth(obj) * 4;
370 pa.pbpa_Left = 0;
371 pa.pbpa_Top = 0;
372 pa.pbpa_Width = _mwidth(obj);
373 pa.pbpa_Height = _mheight(obj);
374 if (DoMethodA(data->dto, (Msg) & pa))
375 WritePixelArrayAlpha(img, 0, 0, _mwidth(obj) * 4,
376 _rp(obj), _mleft(obj), _mtop(obj), _mwidth(obj),
377 _mheight(obj), 0xffffffff);
378 FreeVec((APTR) img);
381 else
383 if (data->bmhd->bmh_Masking == mskHasMask)
385 /* Transparency with mask */
386 APTR mask = NULL;
388 GetDTAttrs(data->dto, PDTA_MaskPlane, (IPTR) & mask,
389 TAG_DONE);
391 if (mask)
392 BltMaskBitMapRastPort(data->bm, 0, 0, _rp(obj),
393 _mleft(obj), _mtop(obj), _mwidth(obj),
394 _mheight(obj), 0xE0, (PLANEPTR) mask);
396 else
398 /* All other cases */
400 struct BitMap *bm = data->bm;
401 if (data->selected)
403 bm = data->bm_selected;
404 D(bug("render selected\n"));
406 else if (data->highlighted)
408 D(bug("render highlighted\n"));
409 bm = data->bm_highlighted;
411 else
413 D(bug("render normal\n"));
416 BltBitMapRastPort(bm, 0, 0, _rp(obj), _mleft(obj),
417 _mtop(obj), _mwidth(obj), _mheight(obj), 0xC0);
422 return 0;
425 IPTR Dtpic__OM_DISPOSE(struct IClass *cl, Object *obj, Msg msg)
427 //struct Dtpic_DATA *data = INST_DATA(cl, obj);
429 return DoSuperMethodA(cl, obj, msg);
432 IPTR Dtpic__OM_SET(struct IClass *cl, Object *obj, struct opSet *msg)
434 struct Dtpic_DATA *data = INST_DATA(cl, obj);
435 struct TagItem *tags = msg->ops_AttrList;
436 struct TagItem *tag;
437 ULONG needs_redraw = 0;
439 while ((tag = NextTagItem(&tags)) != NULL)
441 switch (tag->ti_Tag)
443 case MUIA_Dtpic_Name:
444 /* If no filename or different filenames */
445 if (!data->name || strcmp(data->name, (char *)tag->ti_Data))
447 data->name = (STRPTR)tag->ti_Data;
449 /* Run immediate setup only if base class is setup up */
450 if (_flags(obj) & MADF_SETUP)
451 setup_datatype(cl, obj);
452 needs_redraw = 1;
454 break;
455 case MUIA_Dtpic_Alpha:
456 data->alpha = tag->ti_Data;
457 break;
458 case MUIA_Dtpic_Fade:
459 data->fade = tag->ti_Data;
460 break;
464 update_alpha(data);
465 if (_flags(obj) & MADF_SETUP)
466 change_event_handler(obj, data);
468 if (needs_redraw)
470 MUI_Redraw(obj, MADF_DRAWOBJECT);
473 return DoSuperMethodA(cl, obj, (Msg) msg);
476 IPTR Dtpic__OM_GET(struct IClass *cl, Object *obj, struct opGet *msg)
478 struct Dtpic_DATA *data = INST_DATA(cl, obj);
480 switch (msg->opg_AttrID)
482 case MUIA_Dtpic_Name:
483 *(msg->opg_Storage) = (IPTR) data->name;
484 return TRUE;
485 case MUIA_Dtpic_Alpha:
486 *(msg->opg_Storage) = data->alpha;
487 return TRUE;
488 case MUIA_Dtpic_DarkenSelState:
489 *(msg->opg_Storage) = data->darkenselstate;
490 return TRUE;
491 case MUIA_Dtpic_Fade:
492 *(msg->opg_Storage) = data->fade;
493 return TRUE;
494 case MUIA_Dtpic_LightenOnMouse:
495 *(msg->opg_Storage) = data->lightenonmouse;
496 return TRUE;
499 return DoSuperMethodA(cl, obj, (Msg) msg);
502 IPTR Dtpic__MUIM_HandleEvent(struct IClass *cl, Object *obj,
503 struct MUIP_HandleEvent *msg)
505 struct Dtpic_DATA *data = INST_DATA(cl, obj);
507 if (msg->imsg)
509 switch (msg->imsg->Class)
511 case IDCMP_INTUITICKS:
512 data->currentalpha += data->deltaalpha;
513 if (data->deltaalpha > 0)
515 if (data->currentalpha > data->alpha)
517 // reached target alpha, no more incrementing
518 data->currentalpha = data->alpha;
519 data->deltaalpha = 0;
522 else if (data->deltaalpha < 0)
524 if (data->currentalpha < data->alpha)
526 // reached target alpha, no more decrementing
527 data->currentalpha = data->alpha;
528 data->deltaalpha = 0;
531 D(bug("intuitick %d %d\n", msg->imsg->MouseX, msg->imsg->MouseY));
532 update_alpha(data);
533 change_event_handler(obj, data);
534 MUI_Redraw(obj, MADF_DRAWUPDATE);
536 break;
538 case IDCMP_MOUSEBUTTONS:
539 if (msg->imsg->Code==SELECTDOWN)
541 if (_isinobject(obj, msg->imsg->MouseX, msg->imsg->MouseY))
543 data->selected = TRUE;
544 D(bug("selectdown %d %d\n", msg->imsg->MouseX,
545 msg->imsg->MouseY));
546 MUI_Redraw(obj, MADF_DRAWUPDATE);
549 else if (msg->imsg->Code==SELECTUP)
551 if (_isinobject(obj, msg->imsg->MouseX, msg->imsg->MouseY))
553 data->selected = FALSE;
554 D(bug("selectup %d %d\n", msg->imsg->MouseX,
555 msg->imsg->MouseY));
556 MUI_Redraw(obj, MADF_DRAWUPDATE);
559 break;
561 case IDCMP_MOUSEMOVE:
562 if (_isinobject(obj, msg->imsg->MouseX, msg->imsg->MouseY))
564 data->highlighted = TRUE;
565 D(bug("mouse move %d %d\n", msg->imsg->MouseX,
566 msg->imsg->MouseY));
568 else
570 data->highlighted = FALSE;
572 MUI_Redraw(obj, MADF_DRAWUPDATE);
573 break;
577 return 0;
580 IPTR Dtpic__MUIM_Show(struct IClass *cl, Object *obj,
581 struct MUIP_Show *msg)
583 struct Dtpic_DATA *data = INST_DATA(cl, obj);
584 IPTR retval;
586 retval = DoSuperMethodA(cl, obj, (Msg) msg);
588 change_event_handler(obj, data);
590 return retval;
593 IPTR Dtpic__MUIM_Hide(struct IClass *cl, Object *obj,
594 struct MUIP_Hide *msg)
596 struct Dtpic_DATA *data = INST_DATA(cl, obj);
598 // remove event handler if it was installed
599 if (data->eh_active)
601 DoMethod(_win(obj), MUIM_Window_RemEventHandler, &data->ehn);
602 data->eh_active = FALSE;
605 return DoSuperMethodA(cl, obj, (Msg) msg);
609 #if ZUNE_BUILTIN_DTPIC
610 BOOPSI_DISPATCHER(IPTR, Dtpic_Dispatcher, cl, obj, msg)
612 switch (msg->MethodID)
614 case OM_NEW:
615 return Dtpic__OM_NEW(cl, obj, (APTR)msg);
616 case OM_DISPOSE:
617 return Dtpic__OM_DISPOSE(cl, obj, (APTR)msg);
618 case OM_SET:
619 return Dtpic__OM_SET(cl, obj, (APTR)msg);
620 case OM_GET:
621 return Dtpic__OM_GET(cl, obj, (APTR)msg);
623 case MUIM_Setup:
624 return Dtpic__MUIM_Setup(cl, obj, (APTR)msg);
625 case MUIM_Cleanup:
626 return Dtpic__MUIM_Cleanup(cl, obj, (APTR)msg);
628 case MUIM_Show:
629 return Dtpic__MUIM_Show(cl, obj, (APTR)msg);
630 case MUIM_Hide:
631 return Dtpic__MUIM_Show(cl, obj, (APTR)msg);
633 case MUIM_AskMinMax:
634 return Dtpic__MUIM_AskMinMax(cl, obj, (APTR)msg);
635 case MUIM_Draw:
636 return Dtpic__MUIM_Draw(cl, obj, (APTR)msg);
637 case MUIM_HandleEvent:
638 return Dtpic__MUIM_HandleEvent(cl, obj, (APTR)msg);
640 default:
641 return DoSuperMethodA(cl, obj, msg);
644 BOOPSI_DISPATCHER_END
646 const struct __MUIBuiltinClass _MUI_Dtpic_desc =
648 MUIC_Dtpic,
649 MUIC_Area,
650 sizeof(struct Dtpic_DATA),
651 (void *) Dtpic_Dispatcher
653 #endif /* ZUNE_BUILTIN_DTPIC */