add casts to zune macros to silence some warnings
[tangerine.git] / workbench / libs / asl / colorpickerclass.c
blobc321e29a226948e8d13bb44750d9ba40bd94179b
1 /*
2 Copyright © 1995-2005, The AROS Development Team. All rights reserved.
3 $Id$
4 */
7 #include <proto/exec.h>
8 #include <proto/dos.h>
9 #include <proto/utility.h>
10 #include <proto/intuition.h>
11 #include <proto/graphics.h>
12 #include <exec/memory.h>
13 #include <intuition/screens.h>
14 #include <intuition/cghooks.h>
15 #include <intuition/imageclass.h>
16 #include <intuition/gadgetclass.h>
17 #include <graphics/gfx.h>
19 #include <string.h>
20 #include <math.h>
22 #include "asl_intern.h"
23 #include "layout.h"
25 #define SDEBUG 0
26 #define DEBUG 0
28 #include <aros/debug.h>
30 #define CLASS_ASLBASE ((struct AslBase_intern *)cl->cl_UserData)
31 #define HOOK_ASLBASE ((struct AslBase_intern *)hook->h_Data)
33 #define AslBase CLASS_ASLBASE
35 /********************** ASL CYCLE CLASS **************************************************/
37 #define CYCLEIMAGEWIDTH 19
38 #define ARROWWIDTH 7
39 #define ARROWHEIGHT 4
41 #define ARROW_DOWN 1
42 #define ARROW_UP 2
44 /***********************************************************************************/
46 IPTR AslColorPicker__OM_SET(Class * cl, struct Gadget * g, struct opSet *msg);
48 /***********************************************************************************/
50 static void RenderObject_Update(Class *cl, struct Gadget *g, struct GadgetInfo *gi)
52 struct RastPort *rp;
54 if ((rp = ObtainGIRPort(gi)))
56 DoMethod((Object *)g, GM_RENDER,
57 (IPTR) gi,
58 (IPTR) rp,
59 GREDRAW_UPDATE
62 ReleaseGIRPort(rp);
66 /***********************************************************************************/
68 static void DrawArrow(Class *cl, struct RastPort *rp, WORD x1, WORD y1, WORD type)
70 WORD dy = 1;
72 if (type == ARROW_UP)
74 y1 += 3; dy = -1;
77 RectFill(rp, x1, y1, x1 + 6, y1); y1 += dy;
78 RectFill(rp, x1 + 1, y1, x1 + 5, y1); y1 += dy;
79 RectFill(rp, x1 + 2, y1, x1 + 4, y1); y1 += dy;
81 WritePixel(rp, x1 + 3, y1);
84 /***********************************************************************************/
86 static void DrawCell(Class *cl, struct AslColorPickerData *data, WORD index)
88 WORD x1, y1, x2, y2, col, row;
90 row = index % data->columns;
91 col = index / data->columns;
93 x1 = data->menux1 + row * (data->cellwidth + data->cellspacex);
94 y1 = data->menuy1 + col * (data->cellheight + data->cellspacey);
96 x2 = x1 + data->cellwidth - 1;
97 y2 = y1 + data->cellheight - 1;
99 SetDrMd(data->rp, JAM1);
100 SetAPen(data->rp, data->colortable ? data->colortable[index] : index);
101 RectFill(data->rp, x1, y1, x2, y2);
104 /***********************************************************************************/
106 static void DrawCellMark(Class *cl, struct AslColorPickerData *data, struct DrawInfo *dri, WORD index, BOOL selected)
108 WORD x1, y1, x2, y2, col, row;
110 row = index % data->columns;
111 col = index / data->columns;
113 x1 = data->menux1 + row * (data->cellwidth + data->cellspacex) - 2;
114 y1 = data->menuy1 + col * (data->cellheight + data->cellspacey) - 2;
116 x2 = x1 + data->cellwidth - 1 + 4;
117 y2 = y1 + data->cellheight - 1 + 4;
119 SetDrMd(data->rp, JAM1);
120 SetAPen(data->rp, dri->dri_Pens[selected ? SHADOWPEN : SHINEPEN]);
122 Move(data->rp, x1, y1);
123 Draw(data->rp, x2, y1);
124 Draw(data->rp, x2, y2);
125 Draw(data->rp, x1, y2);
126 Draw(data->rp, x1, y1);
129 /***********************************************************************************/
131 static void DrawAllCells(Class *cl, struct AslColorPickerData *data)
133 WORD i;
135 for(i = 0; i < data->numcolors; i++)
137 DrawCell(cl, data, i);
141 /***********************************************************************************/
143 IPTR AslColorPicker__OM_NEW(Class * cl, Object * o, struct opSet *msg)
145 struct AslColorPickerData *data;
146 struct TagItem fitags[] =
148 {IA_FrameType, FRAME_BUTTON},
149 {IA_EdgesOnly, FALSE },
150 {TAG_DONE , 0UL }
153 struct Gadget *g = (struct Gadget *)DoSuperMethodA(cl, o, (Msg)msg);
154 if (g)
156 data = INST_DATA(cl, g);
158 /* We want to get a GM_LAYOUT message, no matter if gadget is GFLG_RELRIGHT/RELBOTTOM/
159 RELWIDTH/RELHEIGHT or not */
160 g->Flags |= GFLG_RELSPECIAL;
162 data->frame = NewObjectA(NULL, FRAMEICLASS, fitags);
163 if (data->frame)
165 AslColorPicker__OM_SET(cl, g, msg);
167 } else {
169 CoerceMethod(cl, (Object *)g, OM_DISPOSE);
170 g = NULL;
175 return (IPTR)g;
178 /***********************************************************************************/
180 IPTR AslColorPicker__OM_DISPOSE(Class * cl, Object * o, Msg msg)
182 struct AslColorPickerData *data = INST_DATA(cl, o);
184 if (data->frame) DisposeObject(data->frame);
186 return DoSuperMethodA(cl, o, msg);
189 /***********************************************************************************/
191 IPTR AslColorPicker__OM_SET(Class * cl, struct Gadget * g, struct opSet *msg)
193 struct AslColorPickerData *data = INST_DATA(cl, g);
194 struct TagItem *tag;
195 const struct TagItem *tstate = msg->ops_AttrList;
196 IPTR retval, tidata;
198 retval = DoSuperMethod(cl, (Object *)g, OM_SET, (IPTR) msg->ops_AttrList, (IPTR) msg->ops_GInfo);
200 while((tag = NextTagItem(&tstate)))
202 tidata = tag->ti_Data;
204 switch(tag->ti_Tag)
206 case ASLCP_Color:
207 data->color = tidata;
208 retval += 1;
209 break;
211 case ASLCP_ColorTable:
212 data->colortable = (UBYTE *)tidata;
213 retval += 1;
214 break;
216 case ASLCP_NumColors:
217 data->numcolors = tidata;
218 retval += 1;
219 break;
221 } /* switch(tag->ti_Tag) */
223 } /* while((tag = NextTagItem(&tstate))) */
225 if (retval)
227 RenderObject_Update(cl, g, msg->ops_GInfo);
230 return retval;
234 /***********************************************************************************/
236 IPTR AslColorPicker__OM_GET(Class * cl, Object * o, struct opGet *msg)
238 struct AslColorPickerData *data = INST_DATA(cl, o);
239 IPTR retval = 1;
241 switch(msg->opg_AttrID)
243 case ASLCP_Color:
244 *msg->opg_Storage = data->color;
245 break;
247 default:
248 retval = DoSuperMethodA(cl, o, (Msg)msg);
249 break;
252 return retval;
255 /***********************************************************************************/
257 IPTR AslColorPicker__GM_RENDER(Class * cl, struct Gadget * g, struct gpRender *msg)
259 struct AslColorPickerData *data = INST_DATA(cl, g);
260 struct RastPort *rp = msg->gpr_RPort;
261 struct DrawInfo *dri = msg->gpr_GInfo->gi_DrInfo;
262 WORD gadx, gady, gadw, gadh, x, y, y2, a1, a2;
264 if (rp)
266 struct TagItem im_tags[] =
268 {IA_Width , 0 },
269 {IA_Height , 0 },
270 {TAG_DONE }
273 getgadgetcoords(g, msg->gpr_GInfo, &gadx, &gady, &gadw, &gadh);
275 if (msg->gpr_Redraw == GREDRAW_REDRAW)
277 im_tags[0].ti_Data = gadw;
278 im_tags[1].ti_Data = gadh;
280 SetAttrsA(data->frame, im_tags);
282 DrawImageState(msg->gpr_RPort,
283 (struct Image *)data->frame,
284 gadx,
285 gady,
286 (g->Flags & GFLG_SELECTED) ? IDS_SELECTED : IDS_NORMAL,
287 msg->gpr_GInfo->gi_DrInfo);
289 x = gadx + gadw - CYCLEIMAGEWIDTH;
290 y = gady + 2;
291 y2 = gady + gadh - 1 - 2;
293 /* separator bar */
295 SetAPen(rp, dri->dri_Pens[SHINEPEN]);
296 RectFill(rp, x + 1, y , x + 1, y2);
297 SetAPen(rp, dri->dri_Pens[SHADOWPEN]);
298 RectFill(rp, x, y, x, y2);
300 y = gady + (gadh - 4) / 2;
301 x += 6;
303 DrawArrow(cl, rp, x, y, ARROW_DOWN);
306 /* color */
308 a1 = gadx + 3;
309 a2 = gadx + gadw - CYCLEIMAGEWIDTH - 3;
311 SetAPen(rp, data->color);
312 RectFill(rp, a1, gady + 3, a2, gady + gadh - 1 - 3);
314 } /* if (rp) */
316 return (IPTR)0;
319 /***********************************************************************************/
321 IPTR AslColorPicker__GM_GOACTIVE(Class * cl, struct Gadget * g, struct gpInput *msg)
323 struct AslColorPickerData *data = INST_DATA(cl, g);
324 struct DrawInfo *dri = msg->gpi_GInfo->gi_DrInfo;
325 WORD x, y, x2, y2, gadx, gady, gadw, gadh;
326 IPTR rc = GMR_MEACTIVE;
328 if (!msg->gpi_IEvent || !data->numcolors) return GMR_NOREUSE;
330 data->sentgadgetup = FALSE;
332 getgadgetcoords(g, msg->gpi_GInfo, &gadx, &gady, &gadw, &gadh);
334 data->borderleft = 4;
335 data->bordertop = 4;
336 data->borderright = 4;
337 data->borderbottom = 4;
339 if (!data->colortable && data->numcolors > (1L << dri->dri_Depth))
341 data->numcolors = 1L << dri->dri_Depth;
343 #ifdef AROS_NOFPU
345 ULONG n = 0;
347 * Do a sqrt 'by hand'
349 while ((n*n) <= data->numcolors) {
350 n++;
352 if ((n * n) > data->numcolors) {
353 n--;
355 data->rows = n;
357 #else
358 data->rows = (WORD)sqrt((double)data->numcolors);
359 #endif
360 data->columns = (data->numcolors + data->rows - 1) / data->rows;
362 data->cellspacex = 3;
363 data->cellspacey = 3;
365 data->cellwidth = dri->dri_Font->tf_YSize;
366 data->cellheight = data->cellwidth;
368 data->menuwidth = data->columns * data->cellwidth +
369 (data->columns - 1) * data->cellspacex +
370 data->borderleft + data->borderright;
372 data->menuheight = data->rows * data->cellheight +
373 (data->rows - 1) * data->cellspacey +
374 data->bordertop + data->borderbottom;
376 data->menux1 = data->borderleft;
377 data->menuy1 = data->bordertop;
378 data->menux2 = data->menuwidth - data->borderright - 1;
379 data->menuy2 = data->menuheight - data->borderbottom - 1;
382 x = msg->gpi_GInfo->gi_Window->MouseX;
384 x = msg->gpi_GInfo->gi_Window->LeftEdge + gadx;
385 y = msg->gpi_GInfo->gi_Window->TopEdge + gady + gadh;
387 if (x < 0) x = 0;
388 if ((x + data->menuwidth) > msg->gpi_GInfo->gi_Screen->Width)
390 x = msg->gpi_GInfo->gi_Screen->Width - data->menuwidth;
393 if (y < 0) y = 0;
394 if ((y + data->menuheight) > msg->gpi_GInfo->gi_Screen->Height)
396 y = msg->gpi_GInfo->gi_Screen->Height - data->menuheight;
399 x2 = x + data->menuwidth - 1;
400 y2 = y + data->menuheight - 1;
402 if ((data->popupwindow = OpenWindowTags(0,WA_CustomScreen , (IPTR) msg->gpi_GInfo->gi_Screen ,
403 WA_Left , x ,
404 WA_Top , y ,
405 WA_Width , data->menuwidth ,
406 WA_Height , data->menuheight ,
407 WA_Flags , WFLG_BORDERLESS ,
408 WA_BackFill , (IPTR) LAYERS_NOBACKFILL ,
409 TAG_DONE)))
411 data->rp = data->popupwindow->RPort;
413 data->layerx1 = x; data->layery1 = y;
414 data->layerx2 = x2; data->layery2 = y2;
416 data->selected = -1;
417 SetDrMd(data->rp, JAM1);
419 x = 0;
420 y = 0;
421 x2 = x + data->menuwidth - 1;
422 y2 = y + data->menuheight - 1;
424 SetAPen(data->rp, dri->dri_Pens[SHADOWPEN]);
425 RectFill(data->rp, x, y, x2, y);
426 RectFill(data->rp, x2, y + 1, x2, y2);
427 RectFill(data->rp, x, y2, x2 - 1, y2);
428 RectFill(data->rp, x, y + 1, x, y2 - 1);
430 SetAPen (data->rp, dri->dri_Pens[SHINEPEN]);
431 RectFill(data->rp, x + 1, y + 1, x2 - 1, y2 - 1);
433 DrawAllCells(cl, data);
435 else
437 rc = GMR_NOREUSE;
440 return rc;
443 /***********************************************************************************/
445 IPTR AslColorPicker__GM_HANDLEINPUT(Class * cl, struct Gadget * g, struct gpInput *msg)
447 struct AslColorPickerData *data = INST_DATA(cl, g);
448 WORD gadx, gady, gadw, gadh, x, y, sel;
449 IPTR rc = GMR_MEACTIVE;
451 getgadgetcoords(g, msg->gpi_GInfo, &gadx, &gady, &gadw, &gadh);
453 switch(msg->gpi_IEvent->ie_Class)
455 case IECLASS_RAWMOUSE:
456 if (msg->gpi_IEvent->ie_Code == SELECTUP)
458 rc = GMR_NOREUSE;
459 if (data->selected != -1)
461 data->color = data->colortable ? data->colortable[data->selected] : data->selected;
462 data->sentgadgetup = TRUE;
464 rc |= GMR_VERIFY;
465 *msg->gpi_Termination = data->color;
467 break;
469 else if (msg->gpi_IEvent->ie_Code == IECODE_NOBUTTON)
471 /* fall through to IECLASS_TIMER */
473 else
475 break;
477 /* fall through */
479 case IECLASS_TIMER:
480 x = msg->gpi_GInfo->gi_Screen->MouseX - data->layerx1;
481 y = msg->gpi_GInfo->gi_Screen->MouseY - data->layery1;
483 if ((x < data->menux1) || (x > data->menux2) ||
484 (y < data->menuy1) || (y > data->menuy2))
486 if (data->selected != -1)
488 DrawCellMark(cl, data, msg->gpi_GInfo->gi_DrInfo, data->selected, FALSE);
489 data->selected = -1;
492 else
494 x -= data->menux1;
495 y -= data->menuy1;
497 sel = data->columns * (y / (data->cellheight + data->cellspacey)) +
498 x / (data->cellwidth + data->cellspacex);
500 if (sel < 0) sel = 0; /* paranoia */
502 if (sel != data->selected)
504 if (data->selected != -1)
506 DrawCellMark(cl, data, msg->gpi_GInfo->gi_DrInfo, data->selected, FALSE);
507 data->selected = -1;
510 if (sel < data->numcolors)
512 data->selected = sel;
513 DrawCellMark(cl, data, msg->gpi_GInfo->gi_DrInfo, data->selected, TRUE);
518 break;
520 } /* switch(msg->gpi_IEvent->ie_Class) */
522 return rc;
526 /***********************************************************************************/
528 IPTR AslColorPicker__GM_GOINACTIVE(Class * cl, struct Gadget * g, struct gpGoInactive *msg)
530 struct AslColorPickerData *data = INST_DATA(cl, g);
532 if (data->popupwindow)
534 CloseWindow(data->popupwindow);
535 data->popupwindow = 0;
538 if (data->sentgadgetup)
540 RenderObject_Update(cl, g, msg->gpgi_GInfo);
543 return 0;
546 /***********************************************************************************/