minor simplification.
[AROS.git] / workbench / libs / asl / colorpickerclass.c
blob6d6e77f7743206765d14734fd7ebc451d1103356
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <proto/alib.h>
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>
13 #include <exec/memory.h>
14 #include <intuition/screens.h>
15 #include <intuition/cghooks.h>
16 #include <intuition/imageclass.h>
17 #include <intuition/gadgetclass.h>
18 #include <graphics/gfx.h>
20 #include <string.h>
21 #include <math.h>
23 #include "asl_intern.h"
24 #include "layout.h"
26 #define SDEBUG 0
27 #define DEBUG 0
29 #include <aros/debug.h>
31 #define CLASS_ASLBASE ((struct AslBase_intern *)cl->cl_UserData)
32 #define HOOK_ASLBASE ((struct AslBase_intern *)hook->h_Data)
34 #define AslBase CLASS_ASLBASE
36 /********************** ASL CYCLE CLASS **************************************************/
38 #define CYCLEIMAGEWIDTH 19
39 #define ARROWWIDTH 7
40 #define ARROWHEIGHT 4
42 #define ARROW_DOWN 1
43 #define ARROW_UP 2
45 /***********************************************************************************/
47 IPTR AslColorPicker__OM_SET(Class * cl, struct Gadget * g, struct opSet *msg);
49 /***********************************************************************************/
51 static void RenderObject_Update(Class *cl, struct Gadget *g, struct GadgetInfo *gi)
53 struct RastPort *rp;
55 if ((rp = ObtainGIRPort(gi)))
57 DoMethod((Object *)g, GM_RENDER,
58 (IPTR) gi,
59 (IPTR) rp,
60 GREDRAW_UPDATE
63 ReleaseGIRPort(rp);
67 /***********************************************************************************/
69 static void DrawArrow(Class *cl, struct RastPort *rp, WORD x1, WORD y1, WORD type)
71 WORD dy = 1;
73 if (type == ARROW_UP)
75 y1 += 3; dy = -1;
78 RectFill(rp, x1, y1, x1 + 6, y1); y1 += dy;
79 RectFill(rp, x1 + 1, y1, x1 + 5, y1); y1 += dy;
80 RectFill(rp, x1 + 2, y1, x1 + 4, y1); y1 += dy;
82 WritePixel(rp, x1 + 3, y1);
85 /***********************************************************************************/
87 static void DrawCell(Class *cl, struct AslColorPickerData *data, WORD index)
89 WORD x1, y1, x2, y2, col, row;
91 row = index % data->columns;
92 col = index / data->columns;
94 x1 = data->menux1 + row * (data->cellwidth + data->cellspacex);
95 y1 = data->menuy1 + col * (data->cellheight + data->cellspacey);
97 x2 = x1 + data->cellwidth - 1;
98 y2 = y1 + data->cellheight - 1;
100 SetDrMd(data->rp, JAM1);
101 SetAPen(data->rp, data->colortable ? data->colortable[index] : index);
102 RectFill(data->rp, x1, y1, x2, y2);
105 /***********************************************************************************/
107 static void DrawCellMark(Class *cl, struct AslColorPickerData *data, struct DrawInfo *dri, WORD index, BOOL selected)
109 WORD x1, y1, x2, y2, col, row;
111 row = index % data->columns;
112 col = index / data->columns;
114 x1 = data->menux1 + row * (data->cellwidth + data->cellspacex) - 2;
115 y1 = data->menuy1 + col * (data->cellheight + data->cellspacey) - 2;
117 x2 = x1 + data->cellwidth - 1 + 4;
118 y2 = y1 + data->cellheight - 1 + 4;
120 SetDrMd(data->rp, JAM1);
121 SetAPen(data->rp, dri->dri_Pens[selected ? SHADOWPEN : SHINEPEN]);
123 Move(data->rp, x1, y1);
124 Draw(data->rp, x2, y1);
125 Draw(data->rp, x2, y2);
126 Draw(data->rp, x1, y2);
127 Draw(data->rp, x1, y1);
130 /***********************************************************************************/
132 static void DrawAllCells(Class *cl, struct AslColorPickerData *data)
134 WORD i;
136 for(i = 0; i < data->numcolors; i++)
138 DrawCell(cl, data, i);
142 /***********************************************************************************/
144 IPTR AslColorPicker__OM_NEW(Class * cl, Object * o, struct opSet *msg)
146 struct AslColorPickerData *data;
147 struct TagItem fitags[] =
149 {IA_FrameType, FRAME_BUTTON},
150 {IA_EdgesOnly, FALSE },
151 {TAG_DONE , 0UL }
154 struct Gadget *g = (struct Gadget *)DoSuperMethodA(cl, o, (Msg)msg);
155 if (g)
157 data = INST_DATA(cl, g);
159 /* We want to get a GM_LAYOUT message, no matter if gadget is GFLG_RELRIGHT/RELBOTTOM/
160 RELWIDTH/RELHEIGHT or not */
161 g->Flags |= GFLG_RELSPECIAL;
163 data->frame = NewObjectA(NULL, FRAMEICLASS, fitags);
164 if (data->frame)
166 AslColorPicker__OM_SET(cl, g, msg);
168 } else {
170 CoerceMethod(cl, (Object *)g, OM_DISPOSE);
171 g = NULL;
176 return (IPTR)g;
179 /***********************************************************************************/
181 IPTR AslColorPicker__OM_DISPOSE(Class * cl, Object * o, Msg msg)
183 struct AslColorPickerData *data = INST_DATA(cl, o);
185 if (data->frame) DisposeObject(data->frame);
187 return DoSuperMethodA(cl, o, msg);
190 /***********************************************************************************/
192 IPTR AslColorPicker__OM_SET(Class * cl, struct Gadget * g, struct opSet *msg)
194 struct AslColorPickerData *data = INST_DATA(cl, g);
195 struct TagItem *tag, *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 /***********************************************************************************/