Allow multiple volumes with the same name if their creation dates differ.
[AROS.git] / workbench / libs / gadtools / cycleclass.c
blob07c9f03612292cdd285a2bae5dc495375d0d73bb
1 /*
2 Copyright © 1995-2005, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Internal GadTools cycle class.
6 Lang: English
7 */
10 #include <proto/exec.h>
11 #include <exec/libraries.h>
12 #include <exec/memory.h>
13 #include <proto/dos.h>
14 #include <intuition/classes.h>
15 #include <intuition/classusr.h>
16 #include <intuition/gadgetclass.h>
17 #include <intuition/imageclass.h>
18 #include <intuition/intuition.h>
19 #include <intuition/cghooks.h>
20 #include <graphics/rastport.h>
21 #include <graphics/text.h>
22 #include <utility/tagitem.h>
23 #include <devices/inputevent.h>
24 #include <proto/alib.h>
25 #include <proto/utility.h>
27 #include <string.h> /* memset() */
29 #define SDEBUG 0
30 #define DEBUG 0
31 #include <aros/debug.h>
33 #include "gadtools_intern.h"
35 /**********************************************************************************************/
37 #define CYCLEIMAGEWIDTH 19
39 #define GadToolsBase ((struct GadToolsBase_intern *)cl->cl_UserData)
41 /**********************************************************************************************/
43 STATIC VOID rendercyclelabel(Class *cl, struct Gadget *gad, STRPTR string,
44 struct RastPort *rp, struct GadgetInfo *ginfo)
46 UWORD *pens = ginfo->gi_DrInfo->dri_Pens;
47 WORD x,y,h;
48 int len = strlen(string);
50 SetABPenDrMd(rp, pens[TEXTPEN], pens[BACKGROUNDPEN], JAM1);
51 Move(rp,
52 gad->LeftEdge + (gad->Width - CYCLEIMAGEWIDTH - TextLength(rp, string, len)) / 2,
53 gad->TopEdge + (gad->Height - rp->Font->tf_YSize) / 2 + rp->Font->tf_Baseline);
54 Text(rp, string, len);
56 x = gad->LeftEdge + gad->Width - CYCLEIMAGEWIDTH;
58 /* separator bar */
60 SetAPen(rp, pens[SHINEPEN]);
61 RectFill(rp, x + 1, gad->TopEdge + 2, x + 1, gad->TopEdge + gad->Height - 1 - 2);
62 SetAPen(rp, pens[SHADOWPEN]);
63 RectFill(rp, x, gad->TopEdge + 2, x, gad->TopEdge + gad->Height - 1 - 2);
65 /* cycle image */
67 h = gad->Height / 2;
69 x += 6;
71 for(y = 0; y < 4; y++)
73 RectFill(rp,x + y,
74 gad->TopEdge + gad->Height - 1 - h - y - 1,
75 x + 6 - y,
76 gad->TopEdge + gad->Height - 1 - h - y - 1);
78 RectFill(rp,x + y,
79 gad->TopEdge + h + y + 1,
80 x + 6 - y,
81 gad->TopEdge + h + y + 1);
85 /**********************************************************************************************/
87 BOOL pointingadget(struct Gadget *gad, struct GadgetInfo *gi, WORD x, WORD y)
89 WORD gadw, gadh;
91 gadw = gad->Width;
92 if (gad->Flags & GFLG_RELWIDTH) gadw += gi->gi_Domain.Width;
94 gadh = gad->Height;
95 if (gad->Flags & GFLG_RELHEIGHT) gadh += gi->gi_Domain.Height;
97 return ((x >= 0) && (y >= 0) && (x < gadw) && (y < gadh)) ? TRUE : FALSE;
100 /**********************************************************************************************/
102 IPTR GTCycle__OM_NEW(Class *cl, Object *objcl, struct opSet *msg)
104 struct CycleData *data;
105 struct TextAttr *tattr;
106 struct TagItem imgtags[] =
108 { IA_Width , 0 },
109 { IA_Height , 0 },
110 { IA_EdgesOnly , FALSE },
111 { IA_FrameType , FRAME_BUTTON },
112 { TAG_DONE , 0UL }
114 STRPTR *labels;
115 struct Gadget *g;
117 g = (struct Gadget *)DoSuperMethodA(cl, objcl, (Msg)msg);
118 if (!g)
119 return (IPTR)NULL;
121 data = INST_DATA(cl, g);
123 data->active = GetTagData(GTCY_Active, 0, msg->ops_AttrList);
124 data->labels = (STRPTR *)GetTagData(GTCY_Labels, (IPTR)NULL, msg->ops_AttrList);
125 data->labelplace = GetTagData(GA_LabelPlace, GV_LabelPlace_Left, msg->ops_AttrList);
127 data->numlabels = 0;
129 labels = data->labels;
130 if (labels)
132 while (labels[0])
134 data->numlabels++;
135 labels++;
139 tattr = (struct TextAttr *)GetTagData(GA_TextAttr, (IPTR)NULL, msg->ops_AttrList);
140 if (tattr) data->font = OpenFont(tattr);
142 imgtags[0].ti_Data = (IPTR)g->Width;
143 imgtags[1].ti_Data = (IPTR)g->Height;
145 g->GadgetRender = NewObjectA(NULL, FRAMEICLASS, imgtags);
146 if (!(g->GadgetRender))
148 CoerceMethod(cl, (Object *)g, OM_DISPOSE);
149 g = NULL;
152 return (IPTR)g;
155 /**********************************************************************************************/
157 IPTR GTCycle__OM_DISPOSE(Class *cl, struct Gadget * g, Msg msg)
159 struct CycleData *data = INST_DATA(cl, g);
161 if (g->GadgetRender)
162 DisposeObject(g->GadgetRender);
164 if (data->font) CloseFont(data->font);
166 return DoSuperMethodA(cl,(Object *)g,msg);
169 /**********************************************************************************************/
171 IPTR GTCycle__OM_SET(Class *cl, Object *o, struct opSet *msg)
173 struct CycleData *data = INST_DATA(cl, o);
174 struct TagItem *tag;
175 struct TagItem *taglist = msg->ops_AttrList;
176 STRPTR *mylabels;
177 BOOL rerender = FALSE;
178 IPTR result;
180 result = DoSuperMethodA(cl, o, (Msg)msg);
182 while((tag = NextTagItem(&taglist)))
184 switch(tag->ti_Tag)
186 case GTCY_Labels:
187 data->labels = (STRPTR *)tag->ti_Data;
188 data->numlabels = 0;
189 data->active = 0;
190 mylabels = data->labels;
191 if (mylabels)
193 while (mylabels[0])
195 data->numlabels++;
196 mylabels++;
199 rerender = TRUE;
200 break;
202 case GTCY_Active:
203 data->active = tag->ti_Data;
204 rerender = TRUE;
205 break;
207 case GA_Disabled:
208 rerender = TRUE;
209 break;
213 /* SDuvan: Removed test (cl == OCLASS(o)) */
215 if(rerender)
217 struct RastPort *rp;
219 if(data->active > data->numlabels-1)
220 data->active = 0;
222 //kprintf("Rerendering\n");
224 rp = ObtainGIRPort(msg->ops_GInfo);
225 if(rp)
227 DoMethod(o, GM_RENDER, (IPTR)msg->ops_GInfo, (IPTR)rp, GREDRAW_UPDATE);
228 ReleaseGIRPort(rp);
229 result = FALSE;
233 return result;
236 /**********************************************************************************************/
238 IPTR GTCycle__OM_GET(Class *cl, Object *o, struct opGet *msg)
240 struct CycleData *data = INST_DATA(cl, o);
241 IPTR retval = FALSE;
243 switch (msg->opg_AttrID)
245 case GTA_GadgetKind:
246 case GTA_ChildGadgetKind:
247 *(msg->opg_Storage) = CYCLE_KIND;
248 retval = 1UL;
249 break;
251 case GTCY_Active:
252 *(msg->opg_Storage) = (IPTR)data->active;
253 break;
255 case GTCY_Labels:
256 *(msg->opg_Storage) = (IPTR)data->labels;
257 break;
259 default:
260 retval = DoSuperMethodA(cl, o, (Msg)msg);
261 break;
264 return retval;
267 /**********************************************************************************************/
269 IPTR GTCycle__GM_RENDER(Class *cl, struct Gadget *g, struct gpRender *msg)
271 struct CycleData *data = INST_DATA(cl, g);
273 /* Full redraw: clear and draw border */
274 DrawImageState(msg->gpr_RPort,(struct Image *)g->GadgetRender,
275 g->LeftEdge, g->TopEdge,
276 (g->Flags & GFLG_SELECTED)? IDS_SELECTED : IDS_NORMAL,
277 msg->gpr_GInfo->gi_DrInfo);
279 if (data->font)
280 SetFont(msg->gpr_RPort, data->font);
281 else
282 SetFont(msg->gpr_RPort, msg->gpr_GInfo->gi_DrInfo->dri_Font);
284 if (data->labels)
286 rendercyclelabel(cl, g, data->labels[data->active], msg->gpr_RPort, msg->gpr_GInfo);
289 /* Draw disabled pattern */
290 if (g->Flags & GFLG_DISABLED)
292 DoDisabledPattern(msg->gpr_RPort,
293 g->LeftEdge,
294 g->TopEdge,
295 g->LeftEdge + g->Width - 1,
296 g->TopEdge + g->Height - 1,
297 msg->gpr_GInfo->gi_DrInfo->dri_Pens[SHADOWPEN],
298 GadToolsBase);
301 if (msg->gpr_Redraw == GREDRAW_REDRAW)
303 renderlabel(GadToolsBase, g, msg->gpr_RPort, data->labelplace);
306 return 0;
309 /**********************************************************************************************/
311 IPTR GTCycle__GM_HITTEST(Class *cl, struct Gadget *g, struct gpHitTest *msg)
313 return pointingadget(g,
314 msg->gpht_GInfo,
315 msg->gpht_Mouse.X,
316 msg->gpht_Mouse.Y) ? GMR_GADGETHIT : 0;
319 /**********************************************************************************************/
321 IPTR GTCycle__GM_GOACTIVE(Class *cl, struct Gadget *g, struct gpInput *msg)
323 struct RastPort *rp;
324 IPTR retval;
326 g->Flags |= GFLG_SELECTED;
328 rp = ObtainGIRPort(msg->gpi_GInfo);
329 if (rp)
331 struct gpRender rmsg =
333 GM_RENDER,
334 msg->gpi_GInfo,
336 GREDRAW_UPDATE
338 DoMethodA((Object *)g, (Msg)&rmsg);
339 ReleaseGIRPort(rp);
340 retval = GMR_MEACTIVE;
342 else
344 retval = GMR_NOREUSE;
347 return retval;
350 /**********************************************************************************************/
352 IPTR GTCycle__GM_HANDLEINPUT(Class *cl, struct Gadget *g, struct gpInput *msg)
354 struct RastPort *rp;
355 struct CycleData *data;
356 IPTR retval = GMR_MEACTIVE;
358 data = INST_DATA(cl, g);
360 if (msg->gpi_IEvent->ie_Class == IECLASS_RAWMOUSE)
362 if (msg->gpi_IEvent->ie_Code == SELECTUP)
364 if (g->Flags & GFLG_SELECTED)
366 /* mouse is over gadget */
368 data->active++;
369 if (data->active == data->numlabels)
370 data->active = 0;
373 *msg->gpi_Termination = data->active;
374 retval = GMR_NOREUSE | GMR_VERIFY;
376 else
378 /* mouse is not over gadget */
379 retval = GMR_NOREUSE;
383 else if (msg->gpi_IEvent->ie_Code == IECODE_NOBUTTON)
385 struct gpHitTest htmsg =
387 GM_HITTEST,
388 msg->gpi_GInfo,
389 { msg->gpi_Mouse.X, msg->gpi_Mouse.Y },
392 if (DoMethodA((Object *)g, (Msg)&htmsg) != GMR_GADGETHIT)
394 if (g->Flags & GFLG_SELECTED)
396 g->Flags &= ~GFLG_SELECTED;
397 rp = ObtainGIRPort(msg->gpi_GInfo);
398 if (rp)
400 struct gpRender rmsg =
402 GM_RENDER,
403 msg->gpi_GInfo,
405 GREDRAW_UPDATE
408 DoMethodA((Object *)g, (Msg)&rmsg);
409 ReleaseGIRPort(rp);
413 else
415 if (!(g->Flags & GFLG_SELECTED))
417 g->Flags |= GFLG_SELECTED;
418 rp = ObtainGIRPort(msg->gpi_GInfo);
419 if (rp)
421 struct gpRender rmsg =
423 GM_RENDER,
424 msg->gpi_GInfo,
426 GREDRAW_UPDATE
429 DoMethodA((Object *)g, (Msg)&rmsg);
430 ReleaseGIRPort(rp);
435 else if (msg->gpi_IEvent->ie_Code == MENUDOWN)
437 retval = GMR_REUSE;
441 return retval;
444 /**********************************************************************************************/
446 IPTR GTCycle__GM_GOINACTIVE(Class *cl, struct Gadget *g, struct gpGoInactive *msg)
448 struct RastPort *rp;
450 g->Flags &= ~GFLG_SELECTED;
452 rp = ObtainGIRPort(msg->gpgi_GInfo);
453 if (rp)
455 struct gpRender rmsg =
457 GM_RENDER,
458 msg->gpgi_GInfo,
460 GREDRAW_UPDATE
463 DoMethodA((Object *)g, (Msg)&rmsg);
464 ReleaseGIRPort(rp);
467 return 0;
470 /**********************************************************************************************/