Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / workbench / libs / muimaster / classes / gauge.c
blob4e3e9a0fbb5166422b2878afaa6be9670f96b0ec
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 <graphics/gfx.h>
11 #include <graphics/view.h>
12 #include <clib/alib_protos.h>
13 #include <proto/exec.h>
14 #include <proto/graphics.h>
15 #include <proto/utility.h>
16 #include <proto/intuition.h>
17 #include <proto/muimaster.h>
19 #include <string.h>
21 #include "mui.h"
22 #include "muimaster_intern.h"
23 #include "textengine.h"
24 #include "support.h"
25 #include "support_classes.h"
26 #include "gauge_private.h"
28 /* #define MYDEBUG 1 */
29 #include "debug.h"
31 extern struct Library *MUIMasterBase;
34 IPTR Gauge__OM_NEW(struct IClass *cl, Object *obj, struct opSet *msg)
36 struct Gauge_DATA *data;
37 struct TagItem *tag;
38 const struct TagItem *tags;
40 obj = (Object *)DoSuperMethodA(cl, obj, (Msg)msg);
41 if (!obj) return FALSE;
43 data = INST_DATA(cl, obj);
45 data->divide = 1;
46 data->max = 100;
47 data->horiz = FALSE;
48 data->current = 0;
49 data->dupinfo = FALSE;
50 data->info = NULL;
52 /* parse initial taglist */
53 for (tags = msg->ops_AttrList; (tag = NextTagItem(&tags)); )
55 switch (tag->ti_Tag)
57 case MUIA_Gauge_Current:
58 data->current = tag->ti_Data;
59 break;
60 case MUIA_Gauge_Divide:
61 data->divide = tag->ti_Data;
62 break;
63 case MUIA_Gauge_Horiz:
64 data->horiz = tag->ti_Data;
65 break;
66 case MUIA_Gauge_InfoText:
67 data->info = (STRPTR)tag->ti_Data;
68 break;
69 case MUIA_Gauge_Max:
70 data->max = tag->ti_Data;
71 break;
72 case MUIA_Gauge_DupInfoText:
73 data->dupinfo = tag->ti_Data;
74 break;
77 if (data->divide != 0)
78 data->current /= data->divide;
79 if (data->current > data->max)
80 data->current = data->max;
81 if (data->dupinfo)
82 data->info = StrDup(data->info);
84 if (data->info)
86 snprintf(data->buf, GAUGE_BUFSIZE, data->info, data->current);
87 } else data->buf[0] = 0;
89 /* D(bug("Gauge_New(0x%lx, %d)\n",obj,muiAreaData(obj)->mad_Frame)); */
91 return (IPTR)obj;
94 IPTR Gauge__OM_DISPOSE(struct IClass *cl, Object *obj, Msg msg)
96 struct Gauge_DATA *data = INST_DATA(cl,obj);
97 if (data->dupinfo && data->info) FreeVec(data->info);
98 return DoSuperMethodA(cl,obj,msg);
101 IPTR Gauge__OM_SET(struct IClass *cl, Object *obj, struct opSet *msg)
103 struct Gauge_DATA *data;
104 struct TagItem *tag;
105 const struct TagItem *tags;
106 int info_changed = 0;
107 int need_redraw = 0;
109 data = INST_DATA(cl, obj);
111 for (tags = msg->ops_AttrList; (tag = NextTagItem(&tags)); )
113 switch (tag->ti_Tag)
115 case MUIA_Gauge_Current:
116 if (data->current != tag->ti_Data)
118 data->current = tag->ti_Data;
119 info_changed = 1;
120 need_redraw = 1;
122 else
124 tag->ti_Tag = TAG_IGNORE;
126 break;
128 case MUIA_Gauge_Divide:
129 if (data->divide != tag->ti_Data)
131 data->divide = tag->ti_Data;
132 info_changed = 1;
133 need_redraw = 1;
135 else
137 tag->ti_Tag = TAG_IGNORE;
139 break;
141 case MUIA_Gauge_InfoText:
142 if (!data->info || strcmp(data->info, (STRPTR)tag->ti_Data))
144 if (data->dupinfo)
146 if (data->info) FreeVec(data->info);
147 data->info = StrDup((STRPTR)tag->ti_Data);
148 } else
150 data->info = (STRPTR)tag->ti_Data;
152 need_redraw = info_changed = 1;
154 else
156 tag->ti_Tag = TAG_IGNORE;
158 break;
160 case MUIA_Gauge_Max:
161 if (data->max != tag->ti_Data)
163 data->max = tag->ti_Data;
164 need_redraw = 1;
166 else
168 tag->ti_Tag = TAG_IGNORE;
170 break;
174 if (data->divide != 0)
175 data->current /= data->divide;
176 if (data->current > data->max)
177 data->current = data->max;
179 if (info_changed)
181 if (data->info)
183 snprintf(data->buf, GAUGE_BUFSIZE, data->info, data->current);
184 } else data->buf[0] = 0;
187 if (need_redraw)
189 MUI_Redraw(obj,MADF_DRAWOBJECT);
191 return DoSuperMethodA(cl, obj, (Msg)msg);
194 IPTR Gauge__OM_GET(struct IClass *cl, Object * obj, struct opGet *msg)
196 struct Gauge_DATA *data = INST_DATA(cl, obj);
197 ULONG *store = msg->opg_Storage;
198 ULONG tag = msg->opg_AttrID;
200 switch (tag)
202 case MUIA_Gauge_Current:
203 *store = data->current;
204 break;
206 case MUIA_Gauge_Divide:
207 *store = data->divide;
208 break;
210 case MUIA_Gauge_InfoText:
211 *store = (ULONG)data->info;
212 break;
214 case MUIA_Gauge_Max:
215 *store = data->max;
216 break;
218 case MUIA_Gauge_DupInfoText:
219 *store = (ULONG)data->dupinfo;
220 break;
222 default:
223 return DoSuperMethodA(cl, obj, (Msg)msg);
226 return TRUE;
229 IPTR Gauge__MUIM_Setup(struct IClass *cl, Object *obj, struct MUIP_Setup *msg)
231 struct Gauge_DATA *data = INST_DATA(cl,obj);
233 if (!(DoSuperMethodA(cl, obj, (Msg)msg))) return 0;
235 if (data->info)
237 struct RastPort rp;
239 InitRastPort(&rp);
240 SetFont(&rp,_font(obj));
242 data->info_width = TextLength(&rp,data->buf,strlen(data->buf));
243 data->info_height = _font(obj)->tf_YSize;
245 DeinitRastPort(&rp);
246 } else
248 if (data->horiz)
250 data->info_width = 0;
251 data->info_height = 0;
253 else
255 data->info_width = 0;
256 data->info_height = 0;
260 return 1;
263 IPTR Gauge__MUIM_AskMinMax(struct IClass *cl, Object *obj, struct MUIP_AskMinMax *msg)
265 struct Gauge_DATA *data = INST_DATA(cl,obj);
266 DoSuperMethodA(cl,obj,(Msg)msg);
268 if (data->horiz)
270 msg->MinMaxInfo->MinWidth += data->info_width;
271 msg->MinMaxInfo->MinHeight += data->info_height + 2;
272 msg->MinMaxInfo->DefWidth += data->info_width + 10;
273 msg->MinMaxInfo->DefHeight += data->info_height + 2;
274 msg->MinMaxInfo->MaxWidth = MUI_MAXMAX;
275 if (data->info)
276 msg->MinMaxInfo->MaxHeight += data->info_height + 2;
277 else
278 msg->MinMaxInfo->MaxHeight = MUI_MAXMAX;
281 else
283 msg->MinMaxInfo->MinWidth += data->info_width + 2;
284 msg->MinMaxInfo->MinHeight += data->info_height;
285 msg->MinMaxInfo->DefWidth += data->info_width + 2;
286 msg->MinMaxInfo->DefHeight += data->info_height + 10;
287 if (data->info)
288 msg->MinMaxInfo->MaxWidth += data->info_width + 2;
289 else
290 msg->MinMaxInfo->MaxWidth = MUI_MAXMAX;
292 msg->MinMaxInfo->MaxHeight = MUI_MAXMAX;
294 return 0;
297 IPTR Gauge__MUIM_Draw(struct IClass *cl, Object *obj, struct MUIP_Draw *msg)
299 struct Gauge_DATA *data = INST_DATA(cl,obj);
300 //ULONG val;
302 DoSuperMethodA(cl,obj,(Msg)msg);
304 /* D(bug("Gauge_Draw(0x%lx) %ldx%ldx%ldx%ld :: %ldx%ldx%ldx%ld\n",obj,_left(obj),_top(obj),_right(obj),_bottom(obj), _mleft(obj),_mtop(obj), _mright(obj), _mbottom(obj))); */
306 if (data->horiz)
308 ULONG w;
309 if (data->max != 0)
311 w = _mwidth(obj) * data->current / data->max; /* NOTE: should be 64 bit */
312 } else {
313 w = 0;
315 SetABPenDrMd(_rp(obj),_pens(obj)[MPEN_FILL],0,JAM1);
316 RectFill(_rp(obj),_mleft(obj),_mtop(obj),_mleft(obj) + w - 1, _mbottom(obj));
318 if (data->info)
320 ZText *ztext = zune_text_new("\33c\0338",data->buf,ZTEXT_ARG_NONE,0);
321 if (ztext)
323 zune_text_get_bounds(ztext, obj);
324 SetAPen(_rp(obj), _pens(obj)[MPEN_SHINE]);
325 zune_text_draw(ztext, obj, _mleft(obj),_mright(obj),_mtop(obj) + (_mheight(obj) - ztext->height)/2);
326 zune_text_destroy(ztext);
330 else
332 ULONG h;
333 h = _mheight(obj) * data->current / data->max; /* NOTE: should be 64 bit */
335 SetABPenDrMd(_rp(obj),_pens(obj)[MPEN_FILL],0,JAM1);
336 RectFill(_rp(obj),_mleft(obj),_mbottom(obj) - h + 1, _mright(obj),_mbottom(obj));
338 if (data->info)
340 ZText *ztext = zune_text_new("\33c\0338",data->buf,ZTEXT_ARG_NONE,0);
341 if (ztext)
343 zune_text_get_bounds(ztext, obj);
344 SetAPen(_rp(obj), _pens(obj)[MPEN_SHINE]);
345 zune_text_draw(ztext, obj, _mleft(obj),_mright(obj),_mtop(obj) + (_mheight(obj) - ztext->height)/2);
346 zune_text_destroy(ztext);
350 return 0;
354 #if ZUNE_BUILTIN_GAUGE
355 BOOPSI_DISPATCHER(IPTR, Gauge_Dispatcher, cl, obj, msg)
357 switch (msg->MethodID)
359 case OM_NEW: return Gauge__OM_NEW(cl, obj, (struct opSet *)msg);
360 case OM_DISPOSE: return Gauge__OM_DISPOSE(cl, obj, (Msg)msg);
361 case OM_SET: return Gauge__OM_SET(cl, obj, (struct opSet *)msg);
362 case OM_GET: return Gauge__OM_GET(cl, obj, (struct opGet *)msg);
363 case MUIM_Setup: return Gauge__MUIM_Setup(cl, obj, (struct MUIP_Setup *)msg);
364 case MUIM_AskMinMax: return Gauge__MUIM_AskMinMax(cl, obj, (struct MUIP_AskMinMax*)msg);
365 case MUIM_Draw: return Gauge__MUIM_Draw(cl, obj, (struct MUIP_Draw*)msg);
366 default: return DoSuperMethodA(cl, obj, msg);
369 BOOPSI_DISPATCHER_END
371 const struct __MUIBuiltinClass _MUI_Gauge_desc = {
372 MUIC_Gauge,
373 MUIC_Area,
374 sizeof(struct Gauge_DATA),
375 (void*)Gauge_Dispatcher
377 #endif /* ZUNE_BUILTIN_GAUGE */