Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / workbench / libs / muimaster / classes / scale.c
blob366ec6c53e4467201c4d09c8f1429013e0e56673
1 /*
2 Copyright © 2002-2006, 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 "scale_private.h"
28 /* #define MYDEBUG 1 */
29 #include "debug.h"
31 extern struct Library *MUIMasterBase;
34 IPTR Scale__OM_NEW(struct IClass *cl, Object *obj, struct opSet *msg)
36 struct Scale_DATA *data;
37 struct TagItem *tag, *tags;
39 obj = (Object *)DoSuperMethodA(cl, obj, (Msg)msg);
40 if (!obj) return FALSE;
42 data = INST_DATA(cl, obj);
44 data->horiz = TRUE;
46 /* parse initial taglist */
48 for (tags = msg->ops_AttrList; (tag = NextTagItem((const struct TagItem**)&tags)); )
50 switch (tag->ti_Tag)
52 case MUIA_Scale_Horiz:
53 data->horiz = tag->ti_Data;
54 break;
58 D(bug("muimaster.library/scale.c: Scale Object created at 0x%lx\n",obj));
60 return (IPTR)obj;
63 IPTR Scale__OM_SET(struct IClass *cl, Object *obj, struct opSet *msg)
65 struct Scale_DATA *data;
66 struct TagItem *tag, *tags;
67 int need_redraw = 0;
69 data = INST_DATA(cl, obj);
71 for (tags = msg->ops_AttrList; (tag = NextTagItem((const struct TagItem**)&tags)); )
73 switch (tag->ti_Tag)
75 case MUIA_Scale_Horiz:
76 if (data->horiz != tag->ti_Data)
77 need_redraw = 1;
78 data->horiz = tag->ti_Data;
79 break;
83 if (need_redraw)
85 MUI_Redraw(obj,MADF_DRAWOBJECT);
87 return DoSuperMethodA(cl, obj, (Msg)msg);
90 IPTR Scale__OM_GET(struct IClass *cl, Object * obj, struct opGet *msg)
92 struct Scale_DATA *data = INST_DATA(cl, obj);
93 IPTR *store = msg->opg_Storage;
94 IPTR tag = msg->opg_AttrID;
96 switch (tag)
98 case MUIA_Scale_Horiz:
99 *store = (IPTR)data->horiz;
100 return TRUE;
103 return DoSuperMethodA(cl, obj, (Msg)msg);
106 IPTR Scale__MUIM_Setup(struct IClass *cl, Object *obj, struct MUIP_Setup *msg)
108 struct Scale_DATA *data = INST_DATA(cl,obj);
110 if (!(DoSuperMethodA(cl, obj, (Msg)msg))) return 0;
113 char *minlabel = "0% 100%";
114 struct RastPort rp;
116 InitRastPort(&rp);
117 SetFont(&rp,_font(obj));
119 data->label_minwidth = TextLength(&rp,minlabel,strlen(minlabel));
120 data->label_height = _font(obj)->tf_YSize;
122 DeinitRastPort(&rp);
125 return 1;
128 IPTR Scale__MUIM_AskMinMax(struct IClass *cl, Object *obj, struct MUIP_AskMinMax *msg)
130 struct Scale_DATA *data = INST_DATA(cl,obj);
131 DoSuperMethodA(cl,obj,(Msg)msg);
133 if (data->horiz)
135 msg->MinMaxInfo->MinWidth += data->label_minwidth;
136 msg->MinMaxInfo->MinHeight += data->label_height + 4;
137 msg->MinMaxInfo->DefWidth += data->label_minwidth;
138 msg->MinMaxInfo->DefHeight += data->label_height + 4;
139 msg->MinMaxInfo->MaxWidth = MUI_MAXMAX;
140 msg->MinMaxInfo->MaxHeight += data->label_height + 4;
142 else
145 return 0;
148 IPTR Scale__MUIM_Draw(struct IClass *cl, Object *obj, struct MUIP_Draw *msg)
150 struct Scale_DATA *data = INST_DATA(cl,obj);
151 //ULONG val;
153 DoSuperMethodA(cl,obj,(Msg)msg);
154 D(bug("muimaster.library/scale.c: Draw Scale Object at 0x%lx %ldx%ldx%ldx%ld\n",obj,_left(obj),_top(obj),_right(obj),_bottom(obj)));
156 if (data->horiz)
158 int i;
159 //int subdiv;
160 char buf[255];
161 int k;
162 BOOL drawpct;
164 /* main horizontal bar */
165 SetAPen(_rp(obj),_pens(obj)[MPEN_TEXT]);
166 Move(_rp(obj), _mleft(obj), _mtop(obj) + 3);
167 Draw(_rp(obj), _mright(obj), _mtop(obj) + 3);
169 /* testing possible layouts: 1 = 0...100 ; 2 = 0...50..100 ; etc ... */
170 for (i = 2; i < _mwidth(obj); i *= 2)
172 int j;
173 int total_width = 0;
174 int too_big = 0;
176 for (j = 0; j <= i; j++)
178 //int pct = j * 100 / i;
180 snprintf(buf, 255, "%ld%%", (LONG)j);
181 total_width += TextLength(_rp(obj),buf,strlen(buf));
182 if (total_width > (3 * _mwidth(obj) / 8))
184 too_big = 1;
185 break;
188 if (too_big)
189 break;
192 for (k = 0, drawpct = TRUE; k <= i; k++)
194 /* draw 0% */
195 if (k == 0)
197 ZText *ztext = zune_text_new(NULL,"0%",ZTEXT_ARG_NONE,0);
198 if (ztext)
200 zune_text_get_bounds(ztext, obj);
201 zune_text_draw(ztext, obj, _mleft(obj),_mright(obj),_mtop(obj) + 4);
202 zune_text_destroy(ztext);
204 Move(_rp(obj), _mleft(obj), _mtop(obj));
205 Draw(_rp(obj), _mleft(obj), _mtop(obj) + 3);
206 drawpct = FALSE;
208 else if (k == i) /* draw 100% */
210 ZText *ztext = zune_text_new("\33r","100%",ZTEXT_ARG_NONE,0);
211 if (ztext)
213 zune_text_get_bounds(ztext, obj);
214 zune_text_draw(ztext, obj, _mleft(obj),_mright(obj),_mtop(obj) + 4);
215 zune_text_destroy(ztext);
217 Move(_rp(obj), _mright(obj), _mtop(obj));
218 Draw(_rp(obj), _mright(obj), _mtop(obj) + 3);
219 drawpct = FALSE;
221 else if (drawpct == TRUE) /* draw intermediate values and lines */
223 ZText *ztext;
224 int val = k * 100 / i;
226 snprintf(buf, 255, "%ld%%", (LONG)val);
227 ztext = zune_text_new(NULL,buf,ZTEXT_ARG_NONE,0);
228 if (ztext)
230 int width;
231 zune_text_get_bounds(ztext, obj);
232 width = TextLength(_rp(obj),buf,strlen(buf));
233 zune_text_draw(ztext, obj, _mleft(obj) + _mwidth(obj) * k / i - width / 2,_mright(obj),_mtop(obj) + 4);
234 zune_text_destroy(ztext);
236 Move(_rp(obj), _mleft(obj) + _mwidth(obj) * k / i, _mtop(obj));
237 Draw(_rp(obj), _mleft(obj) + _mwidth(obj) * k / i, _mtop(obj) + 3);
238 drawpct = FALSE;
240 else /* draw intermediate lines */
242 Move(_rp(obj), _mleft(obj) + _mwidth(obj) * k / i, _mtop(obj) + 1);
243 Draw(_rp(obj), _mleft(obj) + _mwidth(obj) * k / i, _mtop(obj) + 3);
244 drawpct = TRUE;
248 else
251 return 0;
254 #if ZUNE_BUILTIN_SCALE
255 BOOPSI_DISPATCHER(IPTR, Scale_Dispatcher, cl, obj, msg)
257 switch (msg->MethodID)
259 case OM_NEW: return Scale__OM_NEW(cl, obj, (struct opSet *)msg);
260 case OM_SET: return Scale__OM_SET(cl, obj, (struct opSet *)msg);
261 case OM_GET: return Scale__OM_GET(cl, obj, (struct opGet *)msg);
262 case MUIM_Setup: return Scale__MUIM_Setup(cl, obj, (struct MUIP_Setup *)msg);
263 case MUIM_AskMinMax: return Scale__MUIM_AskMinMax(cl, obj, (struct MUIP_AskMinMax*)msg);
264 case MUIM_Draw: return Scale__MUIM_Draw(cl, obj, (struct MUIP_Draw*)msg);
265 default: return DoSuperMethodA(cl, obj, msg);
268 BOOPSI_DISPATCHER_END
270 const struct __MUIBuiltinClass _MUI_Scale_desc =
272 MUIC_Scale,
273 MUIC_Area,
274 sizeof(struct Scale_DATA),
275 (void*)Scale_Dispatcher
277 #endif /* ZUNE_BUILTIN_SCALE */