Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / workbench / classes / gadgets / aroscycle / cycleclass.c
blob41cd23e556d8d634333af6175cbbdf4edebc2c8c
1 /*
2 Copyright © 1995-2005, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: AROS specific cycle class implementation.
6 Lang: english
7 */
9 /***********************************************************************************/
11 #define USE_BOOPSI_STUBS
12 #include <exec/libraries.h>
13 #include <proto/dos.h>
14 #include <proto/intuition.h>
15 #include <intuition/classes.h>
16 #include <intuition/classusr.h>
17 #include <intuition/imageclass.h>
18 #include <intuition/intuition.h>
19 #include <intuition/screens.h>
20 #include <proto/graphics.h>
21 #include <graphics/rastport.h>
22 #include <graphics/text.h>
23 #include <proto/utility.h>
24 #include <utility/tagitem.h>
25 #include <devices/inputevent.h>
26 #include <gadgets/aroscycle.h>
27 #include <proto/alib.h>
29 #ifndef DEBUG
30 # define DEBUG 0
31 #endif
32 #include <aros/debug.h>
34 #include "aroscycle_intern.h"
36 /***********************************************************************************/
38 #define IM(o) ((struct Image *)(o))
39 #define EG(o) ((struct Gadget *)(o))
41 #include <clib/boopsistubs.h>
43 /***********************************************************************************/
45 Object *AROSCycle__OM_NEW(Class *cl, Class *rootcl, struct opSet *msg)
47 struct CycleData *data;
48 struct TextAttr *tattr;
49 struct TagItem imgtags[] = {
50 { IA_Width , 0 },
51 { IA_Height , 0 },
52 { IA_EdgesOnly , FALSE },
53 { IA_FrameType , FRAME_BUTTON },
54 { TAG_DONE , 0UL }
56 STRPTR *labels;
57 Object *o;
59 o = (Object *)DoSuperMethodA(cl, (Object *)rootcl, (Msg)msg);
60 if (!o)
61 return NULL;
63 data = INST_DATA(cl, o);
64 data->active = GetTagData(AROSCYCLE_Active, 0, msg->ops_AttrList);
65 data->labels = (STRPTR *)GetTagData(AROSCYCLE_Labels, (IPTR) NULL, msg->ops_AttrList);
66 data->numlabels = 0;
68 labels = data->labels;
69 if (labels)
71 while (labels[0])
73 data->numlabels++;
74 labels++;
78 tattr = (struct TextAttr *)GetTagData(GA_TextAttr, (IPTR) NULL, msg->ops_AttrList);
79 if (tattr) data->font = OpenFont(tattr);
81 imgtags[0].ti_Data = (IPTR)EG(o)->Width;
82 imgtags[1].ti_Data = (IPTR)EG(o)->Height;
84 EG(o)->GadgetRender = NewObjectA(NULL, FRAMEICLASS, imgtags);
85 if (!EG(o)->GadgetRender)
87 IPTR methodid = OM_DISPOSE;
88 CoerceMethodA(cl, o, (Msg)&methodid);
89 return NULL;
92 return o;
95 /***********************************************************************************/
97 VOID AROSCycle__OM_DISPOSE(Class *cl, Object *o, Msg msg)
99 struct CycleData *data = INST_DATA(cl, o);
101 if (EG(o)->GadgetRender)
102 DisposeObject(EG(o)->GadgetRender);
104 if (data->font) CloseFont(data->font);
106 DoSuperMethodA(cl,o,msg);
109 /***********************************************************************************/
111 IPTR AROSCycle__OM_GET(Class *cl, Object *o, struct opGet *msg)
113 struct CycleData *data = INST_DATA(cl, o);
114 IPTR retval = 1;
116 switch(msg->opg_AttrID)
118 case AROSCYCLE_Active:
119 *(msg->opg_Storage) = (IPTR)data->active;
120 break;
122 case AROSCYCLE_Labels:
123 *(msg->opg_Storage) = (IPTR)data->labels;
124 break;
126 default:
127 retval = DoSuperMethodA(cl, o, (Msg)msg);
128 break;
131 return retval;
134 /***********************************************************************************/
136 IPTR AROSCycle__OM_SET(Class *cl, Object *o, struct opSet *msg)
138 struct CycleData *data = INST_DATA(cl, o);
139 const struct TagItem *tag, *taglist = msg->ops_AttrList;
140 STRPTR *mylabels;
141 BOOL rerender = FALSE;
142 IPTR result;
144 result = DoSuperMethodA(cl, o, (Msg)msg);
146 while((tag = NextTagItem(&taglist)))
148 switch(tag->ti_Tag)
150 case AROSCYCLE_Labels:
151 data->labels = (STRPTR *)tag->ti_Data;
152 data->numlabels = 0;
153 data->active = 0;
154 mylabels = data->labels;
155 if (mylabels)
157 while (mylabels[0])
159 data->numlabels++;
160 mylabels++;
163 rerender = TRUE;
164 break;
166 case AROSCYCLE_Active:
167 data->active = tag->ti_Data;
168 rerender = TRUE;
169 break;
171 case GA_Disabled:
172 rerender = TRUE;
173 break;
177 /* SDuvan: Removed test (cl == OCLASS(o)) */
179 if(rerender)
181 struct RastPort *rport;
183 if(data->active > data->numlabels-1)
184 data->active = 0;
186 //kprintf("Rerendering\n");
188 rport = ObtainGIRPort(msg->ops_GInfo);
189 if(rport)
191 DoMethod(o, GM_RENDER, (IPTR)msg->ops_GInfo, (IPTR)rport, GREDRAW_UPDATE);
192 ReleaseGIRPort(rport);
193 result = FALSE;
197 return result;
200 /***********************************************************************************/
202 IPTR cycle_hittest(Class *cl, Object *o, struct gpHitTest *msg)
204 return pointingadget((struct Gadget *)o,
205 msg->gpht_GInfo,
206 msg->gpht_Mouse.X,
207 msg->gpht_Mouse.Y) ? GMR_GADGETHIT : 0;
210 /***********************************************************************************/
212 VOID AROSCycle__GM_RENDER(Class *cl, Object *o, struct gpRender *msg)
214 struct CycleData *data = INST_DATA(cl, o);
216 /* Full redraw: clear and draw border */
217 DrawImageState(msg->gpr_RPort,IM(EG(o)->GadgetRender),
218 EG(o)->LeftEdge, EG(o)->TopEdge,
219 EG(o)->Flags&GFLG_SELECTED?IDS_SELECTED:IDS_NORMAL,
220 msg->gpr_GInfo->gi_DrInfo);
222 if (data->font)
223 SetFont(msg->gpr_RPort, data->font);
224 else
225 SetFont(msg->gpr_RPort, msg->gpr_GInfo->gi_DrInfo->dri_Font);
227 if (data->labels)
228 renderlabel(EG(o), data->labels[data->active],
229 msg->gpr_RPort, msg->gpr_GInfo);
231 /* Draw disabled pattern */
232 if (G(o)->Flags & GFLG_DISABLED)
233 drawdisabledpattern(msg->gpr_RPort,
234 msg->gpr_GInfo->gi_DrInfo->dri_Pens[SHADOWPEN],
235 G(o)->LeftEdge, G(o)->TopEdge,
236 G(o)->Width, G(o)->Height);
240 /***********************************************************************************/
242 IPTR AROSCycle__GM_GOACTIVE(Class *cl, Object *o, struct gpInput *msg)
244 struct CycleData *data;
245 struct RastPort *rport;
246 IPTR retval;
248 data = INST_DATA(cl, o);
250 EG(o)->Flags |= GFLG_SELECTED;
252 rport = ObtainGIRPort(msg->gpi_GInfo);
253 if (rport)
255 struct gpRender rmsg =
256 { GM_RENDER, msg->gpi_GInfo, rport, GREDRAW_UPDATE }, *p_rmsg = &rmsg;
257 DoMethodA(o, (Msg)p_rmsg);
258 ReleaseGIRPort(rport);
259 retval = GMR_MEACTIVE;
260 } else
261 retval = GMR_NOREUSE;
263 return retval;
266 /***********************************************************************************/
268 IPTR AROSCycle__GM_HANDLEINPUT(Class *cl, Object *o, struct gpInput *msg)
270 struct RastPort *rport;
271 struct CycleData *data;
272 IPTR retval = GMR_MEACTIVE;
274 data = INST_DATA(cl, o);
276 if (msg->gpi_IEvent->ie_Class == IECLASS_RAWMOUSE)
278 if (msg->gpi_IEvent->ie_Code == SELECTUP)
280 if (G(o)->Flags & GFLG_SELECTED)
282 /* mouse is over gadget */
284 data->active++;
285 if (data->active == data->numlabels)
286 data->active = 0;
289 *msg->gpi_Termination = data->active;
290 retval = GMR_NOREUSE | GMR_VERIFY;
291 } else
292 /* mouse is not over gadget */
293 retval = GMR_NOREUSE;
296 G(o)->Flags &= ~GFLG_SELECTED;
298 rport = ObtainGIRPort(msg->gpi_GInfo);
299 if (rport)
301 struct gpRender rmsg =
302 { GM_RENDER, msg->gpi_GInfo, rport, GREDRAW_UPDATE };
303 DoMethodA(o, (Msg)&rmsg);
304 ReleaseGIRPort(rport);
307 } else if (msg->gpi_IEvent->ie_Code == IECODE_NOBUTTON)
309 struct gpHitTest htmsg =
310 { GM_HITTEST, msg->gpi_GInfo,
311 { msg->gpi_Mouse.X, msg->gpi_Mouse.Y },
312 }, *p_htmsg = &htmsg;
313 if (DoMethodA(o, (Msg)p_htmsg) != GMR_GADGETHIT)
315 if (EG(o)->Flags & GFLG_SELECTED)
317 G(o)->Flags &= ~GFLG_SELECTED;
318 rport = ObtainGIRPort(msg->gpi_GInfo);
319 if (rport)
321 struct gpRender rmsg =
322 { GM_RENDER, msg->gpi_GInfo, rport, GREDRAW_UPDATE }, *p_rmsg = &rmsg;
323 DoMethodA(o, (Msg)p_rmsg);
324 ReleaseGIRPort(rport);
327 } else
329 if (!(EG(o)->Flags & GFLG_SELECTED))
331 EG(o)->Flags |= GFLG_SELECTED;
332 rport = ObtainGIRPort(msg->gpi_GInfo);
333 if (rport)
335 struct gpRender rmsg =
336 { GM_RENDER, msg->gpi_GInfo, rport, GREDRAW_UPDATE }, *p_rmsg = &rmsg;
337 DoMethodA(o, (Msg)p_rmsg);
338 ReleaseGIRPort(rport);
342 } else if (msg->gpi_IEvent->ie_Code == MENUDOWN)
343 retval = GMR_REUSE;
345 return retval;
348 /***********************************************************************************/
350 IPTR AROSCycle__GM_GOINACTIVE(Class *cl, Object *o, struct gpGoInactive *msg)
352 struct RastPort *rport;
354 EG(o)->Flags &= ~GFLG_SELECTED;
356 rport = ObtainGIRPort(msg->gpgi_GInfo);
357 if (rport)
359 struct gpRender rmsg = { GM_RENDER, msg->gpgi_GInfo, rport, GREDRAW_UPDATE }, *p_rmsg = &rmsg;
361 DoMethodA(o, (Msg)p_rmsg);
362 ReleaseGIRPort(rport);
365 return 0;