Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / workbench / libs / muimaster / classes / imagedisplay.c
blob3b70ccf40717c1d3a55e92b4ba1fb501e09f92fc
1 /*
2 Copyright © 2002-2003, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define MUIMASTER_YES_INLINE_STDARG
8 #include <stdio.h>
10 #include <intuition/imageclass.h>
11 #include <graphics/gfx.h>
12 #include <graphics/view.h>
13 #include <clib/alib_protos.h>
14 #include <proto/exec.h>
15 #include <proto/graphics.h>
16 #include <proto/utility.h>
17 #include <proto/intuition.h>
18 #include <proto/muimaster.h>
20 #include <string.h>
22 /* #define MYDEBUG 1 */
23 #include "debug.h"
24 #include "mui.h"
25 #include "muimaster_intern.h"
26 #include "support.h"
27 #include "support_classes.h"
28 #include "imspec.h"
29 #include "imagedisplay_private.h"
31 extern struct Library *MUIMasterBase;
33 #define MIF_FREEVERT (1<<0)
34 #define MIF_FREEHORIZ (1<<1)
37 IPTR Imagedisplay__OM_NEW(struct IClass *cl, Object *obj, struct opSet *msg)
39 struct Imagedisplay_DATA *data;
40 struct TagItem *tag, *tags;
42 D(bug("Imagedisplay_New starts\n"));
44 obj = (Object *)DoSuperMethodA(cl, obj, (Msg)msg);
45 if (!obj) return FALSE;
47 data = INST_DATA(cl, obj);
48 data->flags = MIF_FREEHORIZ | MIF_FREEVERT;
50 /* parse initial taglist */
52 for (tags = msg->ops_AttrList; (tag = NextTagItem((const struct TagItem **)&tags)); )
54 switch (tag->ti_Tag)
56 case MUIA_Imagedisplay_Spec:
57 data->spec = zune_image_spec_duplicate(tag->ti_Data);
58 break;
60 case MUIA_Imagedisplay_UseDefSize:
61 _handle_bool_tag(data->flags, (!tag->ti_Data), (MIF_FREEHORIZ | MIF_FREEVERT));
62 break;
64 case MUIA_Imagedisplay_FreeHoriz:
65 /* MUI implements some tag for optionnally prevent rescaling
66 * of displayed image - without affecting imagedisplay resize -
67 * see MUIPrefs/Buttons/Checkmarks/Look for nonrescaled image,
68 * and try a popimage for yourself to see that by default they
69 * get rescaled. It's not the same effect as MUI_Image_FreeHoriz.
70 * -dlc 20030323
72 _handle_bool_tag(data->flags, tag->ti_Data, MIF_FREEHORIZ);
73 break;
75 case MUIA_Imagedisplay_FreeVert:
76 _handle_bool_tag(data->flags, tag->ti_Data, MIF_FREEVERT);
77 break;
81 if (!data->spec)
83 data->spec = StrDup("0:128");
86 if (!data->spec)
88 CoerceMethod(cl,obj,OM_DISPOSE);
89 return 0;
92 D(bug("Imagedisplay_New(%lx) spec=%lx\n", obj, data->img));
93 return (IPTR)obj;
96 IPTR Imagedisplay__OM_DISPOSE(struct IClass *cl, Object *obj, Msg msg)
98 struct Imagedisplay_DATA *data = INST_DATA(cl, obj);
100 zune_image_spec_free(data->spec);
101 DoSuperMethodA(cl,obj,(Msg)msg);
102 return 0;
105 IPTR Imagedisplay__OM_SET(struct IClass *cl, Object *obj, struct opSet *msg)
107 struct Imagedisplay_DATA *data = INST_DATA(cl, obj);
108 struct TagItem *tag, *tags;
110 for (tags = msg->ops_AttrList; (tag = NextTagItem((const struct TagItem **)&tags)); )
112 switch (tag->ti_Tag)
114 case MUIA_Imagedisplay_Spec:
115 if (data->spec)
116 zune_image_spec_free(data->spec);
117 data->spec = zune_image_spec_duplicate(tag->ti_Data);
119 if (_flags(obj) & MADF_CANDRAW)
120 zune_imspec_hide(data->img);
122 if (_flags(obj) & MADF_SETUP)
124 zune_imspec_cleanup(data->img);
125 data->img = zune_imspec_setup((IPTR)data->spec, muiRenderInfo(obj));
128 if (_flags(obj)&MADF_CANDRAW)
129 zune_imspec_show(data->img, obj);
131 MUI_Redraw(obj,MADF_DRAWOBJECT);
132 break;
136 return (IPTR)DoSuperMethodA(cl,obj,(Msg)msg);
139 IPTR Imagedisplay__OM_GET(struct IClass *cl, Object *obj, struct opGet *msg)
141 struct Imagedisplay_DATA *data = INST_DATA(cl, obj);
142 switch (msg->opg_AttrID)
144 case MUIA_Imagedisplay_Spec:
145 *msg->opg_Storage = (IPTR)data->spec;
146 return(TRUE);
149 return (IPTR)DoSuperMethodA(cl,obj,(Msg)msg);
152 IPTR Imagedisplay__MUIM_Setup(struct IClass *cl, Object *obj, struct MUIP_Setup *msg)
154 struct Imagedisplay_DATA *data = INST_DATA(cl, obj);
156 if (!DoSuperMethodA(cl,obj,(Msg)msg))
157 return 0;
159 if (data->spec)
160 data->img = zune_imspec_setup((IPTR)data->spec, muiRenderInfo(obj));
161 return 1;
164 IPTR Imagedisplay__MUIM_Cleanup(struct IClass *cl, Object *obj, struct MUIP_Cleanup *msg)
166 struct Imagedisplay_DATA *data = INST_DATA(cl, obj);
168 if (data->spec)
169 zune_imspec_cleanup(data->img);
170 return DoSuperMethodA(cl,obj,(Msg)msg);
173 IPTR Imagedisplay__MUIM_AskMinMax(struct IClass *cl, Object *obj, struct MUIP_AskMinMax *msg)
175 DoSuperMethodA(cl,obj,(Msg)msg);
177 msg->MinMaxInfo->MinWidth += 3;
178 msg->MinMaxInfo->MinHeight += 3;
180 msg->MinMaxInfo->DefWidth += 16;
181 msg->MinMaxInfo->DefHeight += 16;
183 msg->MinMaxInfo->MaxWidth = MUI_MAXMAX;
184 msg->MinMaxInfo->MaxHeight = MUI_MAXMAX;
186 return 1;
189 IPTR Imagedisplay__MUIM_Show(struct IClass *cl, Object *obj, struct MUIP_Show *msg)
191 struct Imagedisplay_DATA *data = INST_DATA(cl, obj);
193 DoSuperMethodA(cl,obj,(Msg)msg);
195 if (data->img)
196 zune_imspec_show(data->img, obj);
197 return 1;
200 IPTR Imagedisplay__MUIM_Hide(struct IClass *cl, Object *obj,struct MUIP_Hide *msg)
202 struct Imagedisplay_DATA *data = INST_DATA(cl, obj);
204 if (data->img)
205 zune_imspec_hide(data->img);
207 return DoSuperMethodA(cl,obj,(Msg)msg);
210 IPTR Imagedisplay__MUIM_Draw(struct IClass *cl, Object *obj,struct MUIP_Draw *msg)
212 struct Imagedisplay_DATA *data = INST_DATA(cl, obj);
214 DoSuperMethodA(cl,obj,(Msg)msg);
216 if (!(msg->flags & MADF_DRAWOBJECT))
217 return 0;
219 if (data->img)
221 WORD left, top, width, height;
222 APTR clip;
224 left = _mleft(obj);
225 top = _mtop(obj);
226 width = _mwidth(obj);
227 height = _mheight(obj);
229 /* if either horiz or vert is not rescalable, center it at def size */
230 if (!(data->flags & MIF_FREEVERT) || !(data->flags & MIF_FREEHORIZ))
232 struct MUI_MinMax minmax;
234 zune_imspec_askminmax(data->img, &minmax);
235 data->defwidth = minmax.DefWidth;
236 data->defheight = minmax.DefHeight;
238 if (!(data->flags & MIF_FREEVERT) && (height > data->defheight))
240 WORD freespace = height - data->defheight;
242 top += freespace / 2;
243 height = data->defheight;
246 if (!(data->flags & MIF_FREEHORIZ) && (width > data->defwidth))
248 WORD freespace = width - data->defwidth;
250 left += freespace / 2;
251 width = data->defwidth;
254 else
256 struct MUI_MinMax minmax;
258 zune_imspec_askminmax(data->img, &minmax);
260 if (width > minmax.MaxWidth)
262 width = minmax.MaxWidth;
263 left = _mleft(obj) + (_mwidth(obj) - width) / 2;
266 if (height > minmax.MaxHeight)
268 height = minmax.MaxHeight;
269 top = _mtop(obj) + (_mheight(obj) - height) / 2;
273 clip = MUI_AddClipping(muiRenderInfo(obj), _mleft(obj), _mtop(obj),
274 _mwidth(obj), _mheight(obj));
275 zune_imspec_draw(data->img, muiRenderInfo(obj),
276 left, top, width, height,
277 0, 0, IDS_NORMAL);
278 MUI_RemoveClipping(muiRenderInfo(obj), clip);
281 return 1;
284 IPTR Imagedisplay__MUIM_DragQuery(struct IClass *cl, Object *obj, struct MUIP_DragQuery *msg)
286 IPTR dummy;
288 if (msg->obj == obj)
289 return MUIV_DragQuery_Refuse;
290 if (get(msg->obj, MUIA_Imagedisplay_Spec, &dummy)
291 || get(msg->obj, MUIA_Pendisplay_Spec, &dummy))
292 return MUIV_DragQuery_Accept;
293 return MUIV_DragQuery_Refuse;
296 IPTR Imagedisplay__MUIM_DragDrop(struct IClass *cl, Object *obj, struct MUIP_DragDrop *msg)
298 IPTR spec;
300 if (get(msg->obj, MUIA_Imagedisplay_Spec, &spec))
302 set(obj, MUIA_Imagedisplay_Spec, spec);
304 else if (get(msg->obj, MUIA_Pendisplay_Spec, &spec))
306 char buf[67];
308 strcpy(buf, "2:");
309 strncpy(buf + 2, (const char *)spec, 64);
310 buf[66] = 0;
311 set(obj, MUIA_Imagedisplay_Spec, (IPTR)buf);
313 return 0;
317 #if ZUNE_BUILTIN_IMAGEDISPLAY
318 BOOPSI_DISPATCHER(IPTR, Imagedisplay_Dispatcher, cl, obj, msg)
320 switch (msg->MethodID)
322 case OM_NEW: return Imagedisplay__OM_NEW(cl, obj, (struct opSet *)msg);
323 case OM_DISPOSE: return Imagedisplay__OM_DISPOSE(cl, obj, msg);
324 case OM_SET: return Imagedisplay__OM_SET(cl, obj, (APTR)msg);
325 case OM_GET: return Imagedisplay__OM_GET(cl, obj, (APTR)msg);
326 case MUIM_AskMinMax: return Imagedisplay__MUIM_AskMinMax(cl,obj,(APTR)msg);
327 case MUIM_Setup: return Imagedisplay__MUIM_Setup(cl,obj,(APTR)msg);
328 case MUIM_Cleanup: return Imagedisplay__MUIM_Cleanup(cl,obj,(APTR)msg);
329 case MUIM_Show: return Imagedisplay__MUIM_Show(cl,obj,(APTR)msg);
330 case MUIM_Hide: return Imagedisplay__MUIM_Hide(cl,obj,(APTR)msg);
331 case MUIM_Draw: return Imagedisplay__MUIM_Draw(cl,obj,(APTR)msg);
332 case MUIM_DragQuery: return Imagedisplay__MUIM_DragQuery(cl,obj,(APTR)msg);
333 case MUIM_DragDrop: return Imagedisplay__MUIM_DragDrop(cl,obj,(APTR)msg);
334 default: return DoSuperMethodA(cl, obj, msg);
337 BOOPSI_DISPATCHER_END
339 const struct __MUIBuiltinClass _MUI_Imagedisplay_desc =
341 MUIC_Imagedisplay,
342 MUIC_Area,
343 sizeof(struct Imagedisplay_DATA),
344 (void*)Imagedisplay_Dispatcher
346 #endif /* ZUNE_BUILTIN_IMAGEDISPLAY */