Updated PCI IDs to latest snapshot.
[tangerine.git] / workbench / libs / gadtools / paletteclass.c
blobb9978b09c3cc7377e41b44db2fd9cb91cf052bbd
1 /*
2 Copyright © 1995-2005, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Internal GadTools palette 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() */
28 #include <stdlib.h>
30 #define SDEBUG 0
31 #define DEBUG 0
32 #include <aros/debug.h>
34 #include "gadtools_intern.h"
36 /**********************************************************************************************/
38 #define HSPACING 2
39 #define VSPACING 2
41 #define HBORDER HSPACING
42 #define VBORDER VSPACING
45 #define HSELBORDER 1
46 #define VSELBORDER 1
48 #define GadToolsBase ((struct GadToolsBase_intern *)cl->cl_UserData)
50 /**********************************************************************************************/
52 STATIC VOID RenderFrame(struct PaletteData *data, struct RastPort *rp, struct IBox *gadbox,
53 struct DrawInfo *dri, BOOL recessed, BOOL edgesonly, Class *cl);
55 /**********************************************************************************************/
57 STATIC VOID GetGadgetIBox(struct Gadget *g, struct GadgetInfo *gi, struct IBox *ibox)
59 ibox->Left = g->LeftEdge;
60 ibox->Top = g->TopEdge;
61 ibox->Width = g->Width;
62 ibox->Height = g->Height;
64 if (gi)
66 if (g->Flags & GFLG_RELRIGHT)
67 ibox->Left += gi->gi_Domain.Width - 1;
69 if (g->Flags & GFLG_RELBOTTOM)
70 ibox->Top += gi->gi_Domain.Height - 1;
72 if (g->Flags & GFLG_RELWIDTH)
73 ibox->Width += gi->gi_Domain.Width;
75 if (g->Flags & GFLG_RELHEIGHT)
76 ibox->Height += gi->gi_Domain.Height;
80 /**********************************************************************************************/
82 STATIC UWORD GetPalettePen(struct PaletteData *data, UWORD idx)
84 UWORD pen;
86 if (data->pd_ColorTable)
87 pen = data->pd_ColorTable[idx];
88 else
89 pen = idx + data->pd_ColorOffset;
91 return (pen);
94 /**********************************************************************************************/
96 STATIC UBYTE Colors2Depth(UWORD numcolors)
98 UBYTE depth = 0;
100 while ((1 << depth) < numcolors)
101 depth ++;
103 return (depth);
106 /**********************************************************************************************/
108 STATIC BOOL InsidePalette(struct PaletteData *data, WORD x, WORD y)
110 (void)data;
111 (void)x;
112 (void)y;
114 return TRUE;
117 /**********************************************************************************************/
119 STATIC UWORD ComputeColor(struct PaletteData *data, WORD x, WORD y)
121 UWORD row, col;
123 WORD color;
125 col = (x - data->pd_PaletteBox.Left) / data->pd_ColWidth;
126 row = (y - data->pd_PaletteBox.Top) / data->pd_RowHeight;
128 color = data->pd_NumCols *row + col;
130 if (color < 0)
132 color = 0;
134 else if (color >= data->pd_NumColors)
136 color = data->pd_NumColors - 1;
139 return (UWORD)color;
142 /**********************************************************************************************/
144 #define MIN(a, b) (( a < b) ? a : b)
146 STATIC VOID RenderPalette(struct PaletteData *data, struct RastPort *rp, Class *cl)
148 UWORD currentcolor = data->pd_ColorOffset, colors_left;
149 WORD left, top;
150 register UWORD col, row;
151 struct IBox *pbox = &(data->pd_PaletteBox);
153 EnterFunc(bug("RenderPalette(data=%p, rp=%p)\n", data, rp));
155 top = pbox->Top;
157 colors_left = data->pd_NumColors;
158 SetDrMd(rp, JAM1);
160 for (row = data->pd_NumRows; row; row --)
162 left = pbox->Left;
163 for (col = MIN(data->pd_NumCols, colors_left); col; col --)
166 SetAPen(rp, GetPalettePen(data, currentcolor));
168 RectFill(rp, left, top,
169 left + data->pd_ColWidth - VSPACING - 1,
170 top + data->pd_RowHeight - HSPACING - 1 );
172 D(bug("Rectfilling area (%d, %d, %d, %d)\n with color %d", left, top,
173 left + data->pd_ColWidth - VSPACING - 1, top + data->pd_RowHeight - HSPACING,
174 currentcolor));
176 currentcolor ++;
178 left += data->pd_ColWidth;
180 } /* for (each row) */
181 top += data->pd_RowHeight;
183 colors_left -= data->pd_NumCols;
185 } /* for (each column) */
187 ReturnVoid("RenderPalette");
190 /**********************************************************************************************/
192 VOID UpdateActiveColor( struct PaletteData *data,
193 struct DrawInfo *dri,
194 struct RastPort *rp,
195 Class *cl)
197 struct IBox framebox;
198 WORD left, top, right, bottom;
200 EnterFunc(bug("UpdateActiveColor(data=%p, dri=%p, rp=%p)\n",
201 data, dri, rp));
203 SetAPen(rp, dri->dri_Pens[BACKGROUNDPEN]);
204 SetDrMd(rp, JAM1);
206 if (data->pd_OldColor != data->pd_Color)
209 left = data->pd_PaletteBox.Left + (data->pd_OldColor % data->pd_NumCols) *data->pd_ColWidth;
210 top = data->pd_PaletteBox.Top + (data->pd_OldColor / data->pd_NumCols) *data->pd_RowHeight;
212 D(bug("clearing old selected: (%d, %d, %d, %d) oldcolor=%d\n",
213 left, top, left + data->pd_ColWidth, top + data->pd_RowHeight, data->pd_OldColor));
215 /* Clear area with BACKGROUNDPEN */
216 RectFill(rp,
217 left - VBORDER,
218 top - HBORDER,
219 left + data->pd_ColWidth - 1,
220 top + data->pd_RowHeight - 1);
222 /* Rerender in original color */
223 SetAPen(rp, GetPalettePen(data, data->pd_OldColor + data->pd_ColorOffset));
225 RectFill(rp, left, top,
226 left + data->pd_ColWidth - VSPACING - 1,
227 top + data->pd_RowHeight - HSPACING - 1);
231 left = data->pd_PaletteBox.Left + (data->pd_Color % data->pd_NumCols) *data->pd_ColWidth;
232 top = data->pd_PaletteBox.Top + (data->pd_Color / data->pd_NumCols) *data->pd_RowHeight;
234 /* Right & bottom of *colored* area */
235 right = left + data->pd_ColWidth - VSPACING - 1;
236 bottom = top + data->pd_RowHeight - HSPACING - 1;
238 /* Render new active entry */
239 D(bug("rendering new selected: (%d, %d, %d, %d), color=%d\n",
240 left, top, right, bottom, data->pd_Color));
243 if ((right - left >= 6) && (bottom - top >= 6))
245 /* Draw some borders */
247 SetAPen(rp, dri->dri_Pens[BACKGROUNDPEN]);
249 /* We draw left & right from top to bottom, but draw top & bottom
250 ** so they don't overlap with what's allready drawn
253 /* left */
254 RectFill(rp, left, top,
255 left + 1, bottom);
257 /* right */
258 RectFill(rp, right - 1, top,
259 right, bottom);
261 /* top */
262 RectFill(rp, left + 2, top,
263 right - 2, top + 1);
265 /* bottom */
266 RectFill(rp, left + 2, bottom - 1,
267 right - 2, bottom);
270 /* Draw recessed frame around selected color */
271 framebox.Left = left - VBORDER;
272 framebox.Top = top - HBORDER;
273 framebox.Width = data->pd_ColWidth + VBORDER;
274 framebox.Height = data->pd_RowHeight + HBORDER;
276 RenderFrame(data, rp, &framebox, dri, TRUE, TRUE, cl);
278 /* The newly update color becomes the new OldColor */
279 data->pd_OldColor = data->pd_Color;
281 ReturnVoid("UpdateActiveColor");
284 /**********************************************************************************************/
286 STATIC VOID RenderFrame(struct PaletteData *data, struct RastPort *rp, struct IBox *gadbox,
287 struct DrawInfo *dri, BOOL recessed, BOOL edgesonly, Class *cl)
289 WORD left, top, right, bottom;
291 EnterFunc(bug("RenderFrame(rp=%p, gadbox=%p, dri=%p)\n",
292 rp, gadbox, dri));
294 left = gadbox->Left; top = gadbox->Top;
295 right = left + gadbox->Width - 1; bottom = top + gadbox->Height - 1;
297 if (!data->pd_Frame)
299 struct TagItem frame_tags[] =
301 {IA_Resolution , (dri->dri_Resolution.X << 16) + dri->dri_Resolution.Y},
302 {IA_FrameType , FRAME_BUTTON },
303 {IA_EdgesOnly , edgesonly },
304 {TAG_DONE }
307 data->pd_Frame = NewObjectA(NULL, FRAMEICLASS, frame_tags);
310 if (data->pd_Frame)
312 struct TagItem frameset_tags[] =
314 {IA_Width , gadbox->Width },
315 {IA_Height , gadbox->Height },
316 {IA_Recessed , recessed },
317 {IA_EdgesOnly , edgesonly },
318 {TAG_DONE }
321 SetAttrsA(data->pd_Frame, frameset_tags);
323 DrawImageState(rp,
324 (struct Image *)data->pd_Frame,
325 left,
326 top,
327 IDS_NORMAL,
328 dri);
332 ReturnVoid("RenderFrame");
335 /**********************************************************************************************/
337 STATIC IPTR palette_set(Class *cl, Object *o, struct opSet *msg)
339 struct TagItem *tag;
340 const struct TagItem *tstate = msg->ops_AttrList;
341 struct PaletteData *data = INST_DATA(cl, o);
342 BOOL labelplace_set = FALSE, relayout = FALSE;
343 BOOL colortag_found = FALSE, numcolorstag_found = FALSE;
344 IPTR retval = 0UL;
347 EnterFunc(bug("Palette::Set()\n"));
349 while ((tag = NextTagItem(&tstate)))
351 IPTR tidata = tag->ti_Data;
354 switch (tag->ti_Tag)
356 case GTPA_Depth: /* [ISU] */
357 /* NumColors tag overrides Depth tag! */
358 if (!numcolorstag_found)
360 data->pd_NumColors = (1 << ((UBYTE)tidata));
362 D(bug("Depth initialized to %d\n", tidata));
363 relayout = TRUE;
364 retval = 1UL;
366 break;
368 case GTPA_Color: /* [IS] */
369 colortag_found = TRUE;
371 data->pd_OldColor = data->pd_Color;
372 data->pd_Color = (UBYTE)tidata;
373 D(bug("Color set to %d\n", tidata));
374 retval = 1UL;
375 break;
377 case GTPA_ColorOffset: /* [I] */
378 data->pd_ColorOffset = (UBYTE)tidata;
379 D(bug("ColorOffset initialized to %d\n", tidata));
380 retval = 1UL;
381 break;
383 case GTPA_IndicatorWidth: /* [I] */
384 data->pd_IndWidth = (UWORD)tidata;
385 D(bug("Indicatorwidth set to %d\n", tidata));
387 /* If palette has an indictor on left, GA_LabelPlace
388 ** defaults to GV_LabelPlace_Left
390 if (!labelplace_set)
391 data->pd_LabelPlace = GV_LabelPlace_Left;
392 break;
394 case GTPA_IndicatorHeight: /* [I] */
395 data->pd_IndHeight = (UWORD)tidata;
396 D(bug("Indicatorheight set to %d\n", tidata));
397 break;
399 case GA_LabelPlace: /* [I] */
400 data->pd_LabelPlace = (LONG)tidata;
401 D(bug("Labelplace set to %d\n", tidata));
403 labelplace_set = TRUE;
404 break;
406 case GA_TextAttr: /* [I] */
407 data->pd_TAttr = (struct TextAttr *)tidata;
408 D(bug("TextAttr set to %s %d\n",
409 data->pd_TAttr->ta_Name, data->pd_TAttr->ta_YSize));
410 break;
412 case GTPA_ColorTable:
413 data->pd_ColorTable = (UBYTE *)tidata;
414 break;
416 case GTPA_NumColors:
417 numcolorstag_found = TRUE;
419 data->pd_NumColors = (UWORD)tidata;
420 relayout = TRUE;
421 break;
423 } /* switch (tag->ti_Tag) */
425 } /* for (each attr in attrlist) */
427 if (colortag_found)
429 /* convert pen number to index */
431 if (data->pd_ColorTable)
433 WORD i;
435 /* convert pen number to index number */
436 for(i = 0; i < data->pd_NumColors; i++)
438 if (data->pd_ColorTable[i] == data->pd_Color)
440 data->pd_Color = i;
441 break;
445 } else {
446 data->pd_Color -= data->pd_ColorOffset;
449 } /* if (colortag_found) */
451 if (relayout)
453 /* Check if the old selected fits into the new depth */
454 if (data->pd_Color > data->pd_NumColors - 1)
456 data->pd_Color = 0;
457 data->pd_OldColor = 0; /* So that UpdateActiveColor() don't get confused */
460 /* Relayout the gadget */
461 DoMethod(o, GM_LAYOUT, (IPTR) msg->ops_GInfo, FALSE);
464 ReturnPtr ("Palette::Set", IPTR, retval);
467 /**********************************************************************************************/
469 IPTR GTPalette__OM_GET(Class *cl, Object *o, struct opGet *msg)
471 struct PaletteData *data = INST_DATA(cl, o);
472 IPTR retval = 0;
474 switch (msg->opg_AttrID)
476 case GTA_GadgetKind:
477 case GTA_ChildGadgetKind:
478 *(msg->opg_Storage) = PALETTE_KIND;
479 retval = 1UL;
480 break;
482 case GTPA_Color:
483 *msg->opg_Storage = (IPTR)GetPalettePen(data, data->pd_Color);
484 break;
486 case GTPA_ColorOffset:
487 *msg->opg_Storage = (IPTR)data->pd_ColorOffset;
488 break;
490 case GTPA_ColorTable:
491 *msg->opg_Storage = (IPTR)data->pd_ColorTable;
492 break;
494 default:
495 retval = DoSuperMethodA(cl, o, (Msg)msg);
496 break;
499 return retval;
502 /**********************************************************************************************/
504 IPTR GTPalette__OM_NEW(Class *cl, Object *o, struct opSet *msg)
506 struct opSet ops;
507 struct TagItem tags[] =
509 {GA_RelSpecial , TRUE},
510 {TAG_MORE , (IPTR)NULL}
513 EnterFunc(bug("Palette::New()\n"));
515 tags[1].ti_Data = (IPTR)msg->ops_AttrList;
517 ops.MethodID = OM_NEW;
518 ops.ops_GInfo = NULL;
519 ops.ops_AttrList = &tags[0];
521 o = (Object *)DoSuperMethodA(cl, o, (Msg)&ops);
522 if (o)
524 struct PaletteData *data = INST_DATA(cl, o);
526 /* Set some defaults */
527 data->pd_NumColors = 2;
528 data->pd_ColorTable = NULL;
529 data->pd_Color = 0;
530 data->pd_OldColor = 0 ; /* = data->pd_OldColor */
531 data->pd_ColorOffset = 0;
532 data->pd_IndWidth = 0;
533 data->pd_IndHeight = 0;
534 data->pd_LabelPlace = GV_LabelPlace_Above;
536 palette_set(cl, o, msg);
539 ReturnPtr ("Palette::New", IPTR, (IPTR)o);
542 /**********************************************************************************************/
544 IPTR GTPalette__OM_DISPOSE(Class *cl, Object *o, Msg msg)
546 struct PaletteData *data = INST_DATA(cl, o);
548 if (data->pd_Frame) DisposeObject(data->pd_Frame);
550 return DoSuperMethodA(cl, o, msg);
553 /**********************************************************************************************/
555 IPTR GTPalette__GM_LAYOUT(Class *cl, struct Gadget *g, struct gpLayout *msg)
558 /* The palette gadget has been resized and we need to update our layout */
560 struct PaletteData *data = INST_DATA(cl, g);
561 struct IBox *gbox = &(data->pd_GadgetBox),
562 *pbox = &(data->pd_PaletteBox),
563 *indbox = &(data->pd_IndicatorBox);
566 UWORD cols, rows;
568 WORD factor1, factor2, ratio;
569 UWORD fault, smallest_so_far;
571 UWORD *largest, *smallest;
573 WORD leftover_width, leftover_height;
575 EnterFunc(bug("Palette::Layout()\n"));
577 if (!msg->gpl_GInfo)
578 ReturnInt("Palette::Layout", IPTR, 0); /* We MUST have a GInfo to get screen aspect ratio */
580 /* Delete the old gadget box */
581 if (!msg->gpl_Initial)
584 struct RastPort *rp;
586 if ((rp = ObtainGIRPort(msg->gpl_GInfo)))
588 SetAPen(rp, msg->gpl_GInfo->gi_DrInfo->dri_Pens[BACKGROUNDPEN]);
589 D(bug("Clearing area (%d, %d, %d, %d)\n",
590 gbox->Left, gbox->Top, gbox->Left + gbox->Width, gbox->Top + gbox->Height));
591 RectFill(rp, gbox->Left, gbox->Top,
592 gbox->Left + gbox->Width - 1, gbox->Top + gbox->Height - 1);
594 ReleaseGIRPort(rp);
598 /* get the IBox surrounding the whole palette */
599 GetGadgetIBox(g, msg->gpl_GInfo, gbox);
601 D(bug("Got palette ibox: (%d, %d, %d, %d)\n",
602 gbox->Left, gbox->Top, gbox->Width, gbox->Height));
604 /* Get the palette box */
605 pbox->Left = gbox->Left + VBORDER + VSPACING;
606 pbox->Top = gbox->Top + HBORDER + HSPACING;
607 pbox->Width = gbox->Width - VBORDER *2 - VSPACING *2;
608 pbox->Height = gbox->Height - HBORDER *2 - HSPACING *2;
611 /* If we have an indicator box then account for this */
612 if (data->pd_IndHeight)
614 indbox->Top = pbox->Top;
615 indbox->Left = pbox->Left;
616 indbox->Width = pbox->Width;
617 indbox->Height = data->pd_IndHeight;
619 pbox->Height -= (indbox->Height + HSPACING *2);
620 pbox->Top += (data->pd_IndHeight + HSPACING *2);
622 else if (data->pd_IndWidth)
624 indbox->Left = pbox->Left;
625 indbox->Top = pbox->Top;
626 indbox->Width = data->pd_IndWidth;
627 indbox->Height = pbox->Height;
629 pbox->Width -= (indbox->Width + VSPACING *2);
630 pbox->Left += (data->pd_IndWidth + VSPACING *2);
634 /* Compute initial aspect ratio */
635 if (pbox->Width > pbox->Height)
637 cols = pbox->Width / pbox->Height;
638 rows = 1;
639 largest = &cols;
640 smallest = &rows;
642 else
644 rows = pbox->Height / pbox->Width;
645 cols = 1;
646 largest = &rows;
647 smallest = &cols;
650 D(bug("Biggest aspect: %d\n", *largest));
652 ratio = *largest;
654 smallest_so_far = 0xFFFF;
656 factor1 = 1 << Colors2Depth(data->pd_NumColors);
657 factor2 = 1;
659 while (factor1 >= factor2)
662 D(bug("trying aspect %dx%d\n", factor1, factor2));
664 fault = abs(ratio - (factor1 / factor2));
665 D(bug("Fault: %d, smallest fault so far: %d\n", fault, smallest_so_far));
667 if (fault < smallest_so_far)
669 *largest = factor1;
670 *smallest = factor2;
672 smallest_so_far = fault;
675 factor1 >>= 1;
676 factor2 <<= 1;
680 data->pd_NumCols = (UBYTE)cols;
681 data->pd_NumRows = (UBYTE)rows;
683 data->pd_ColWidth = pbox->Width / data->pd_NumCols;
684 data->pd_RowHeight = pbox->Height / data->pd_NumRows;
686 D(bug("cols=%d, rows=%d\n", data->pd_NumCols, data->pd_NumRows));
687 D(bug("colwidth=%d, rowheight=%d\n", data->pd_ColWidth, data->pd_RowHeight));
689 /* Adjust the pbox's and indbox's height according to leftovers */
691 leftover_width = pbox->Width % data->pd_NumCols;
692 leftover_height = pbox->Height % data->pd_NumRows;
694 pbox->Width -= leftover_width;
695 pbox->Height -= leftover_height;
697 if (data->pd_IndHeight)
698 indbox->Width -= leftover_width;
699 else if (data->pd_IndWidth)
700 indbox->Height -= leftover_height;
702 ReturnInt ("Palette::Layout", IPTR, 0);
706 /**********************************************************************************************/
708 IPTR GTPalette__GM_RENDER(Class *cl, struct Gadget *g, struct gpRender *msg)
710 struct PaletteData *data = INST_DATA(cl, g);
712 struct DrawInfo *dri = msg->gpr_GInfo->gi_DrInfo;
713 struct RastPort *rp;
714 struct IBox *gbox = &(data->pd_GadgetBox);
716 EnterFunc(bug("Palette::Render()\n"));
718 rp = msg->gpr_RPort;
720 switch (msg->gpr_Redraw)
722 case GREDRAW_REDRAW:
723 D(bug("Doing total redraw\n"));
725 /* Render gadget label in correct position */
726 renderlabel(GadToolsBase, g, rp, data->pd_LabelPlace);
728 RenderFrame(data, rp, gbox, dri, FALSE, FALSE, cl);
730 RenderPalette(data, rp, cl);
732 /* Render frame aroun ibox */
733 if (data->pd_IndWidth || data->pd_IndHeight)
735 RenderFrame(data, rp, &(data->pd_IndicatorBox), dri, TRUE, TRUE, cl);
738 case GREDRAW_UPDATE:
739 D(bug("Doing redraw update\n"));
741 UpdateActiveColor(data, dri, rp, cl);
743 if (data->pd_IndWidth || data->pd_IndHeight)
745 struct IBox *ibox = &(data->pd_IndicatorBox);
747 SetAPen(rp, GetPalettePen(data, data->pd_Color));
749 D(bug("Drawing indocator at: (%d, %d, %d, %d)\n",
750 ibox->Left, ibox->Top,
751 ibox->Left + ibox->Width, ibox->Top + ibox->Height));
753 RectFill(msg->gpr_RPort,
754 ibox->Left + VBORDER + VSPACING,
755 ibox->Top + HBORDER + HSPACING,
756 ibox->Left + ibox->Width - 1 - VBORDER - VSPACING,
757 ibox->Top + ibox->Height - 1 - HBORDER - HSPACING);
760 break;
763 } /* switch (redraw method) */
765 if (g->Flags & GFLG_DISABLED)
767 DoDisabledPattern(rp,
768 gbox->Left,
769 gbox->Top,
770 gbox->Left + gbox->Width - 1,
771 gbox->Top + gbox->Height - 1,
772 dri->dri_Pens[SHADOWPEN],
773 GadToolsBase);
776 ReturnInt ("Palette::Render", IPTR, 0);
779 /**********************************************************************************************/
781 IPTR GTPalette__GM_HITTEST(Class *cl, Object *o, struct gpHitTest *msg)
783 struct PaletteData *data = INST_DATA(cl, o);
784 WORD x, y;
786 IPTR retval = 0UL;
788 EnterFunc(bug("Palette::HitTest()\n"));
790 /* One might think that this method is not necessary to implement,
791 ** but here is an example to show the opposite:
792 ** Consider a 16 color palette with 8 rows and 2 cols.
793 ** Gadget is 87 pix. heigh. Each row will then be 10 pix hight + 7 pix
794 ** of "nowhere". To prevent anything from happening when this area is
795 ** clicked, we rule it out here.
798 x = msg->gpht_Mouse.X + data->pd_GadgetBox.Left;
799 y = msg->gpht_Mouse.Y + data->pd_GadgetBox.Top;
801 if ( (x > data->pd_PaletteBox.Left)
802 && (x < data->pd_PaletteBox.Left + data->pd_PaletteBox.Width - 1)
803 && (y > data->pd_PaletteBox.Top)
804 && (y < data->pd_PaletteBox.Top + data->pd_PaletteBox.Height - 1)
807 retval = GMR_GADGETHIT;
810 ReturnInt ("Palette::HitTest", IPTR, retval);
813 /**********************************************************************************************/
815 IPTR GTPalette__GM_GOACTIVE(Class *cl, struct Gadget *g, struct gpInput *msg)
817 struct PaletteData *data = INST_DATA(cl, g);
818 IPTR retval = 0UL;
820 EnterFunc(bug("Palette::GoActive()\n"));
821 if (g->Flags & GFLG_DISABLED)
823 retval = GMR_NOREUSE;
825 else
827 if (msg->gpi_IEvent)
829 UBYTE clicked_color;
831 /* Set temporary active to the old active */
832 data->pd_ColorBackup = data->pd_Color;
834 clicked_color = ComputeColor(data,
835 msg->gpi_Mouse.X + data->pd_GadgetBox.Left,
836 msg->gpi_Mouse.Y + data->pd_GadgetBox.Top);
838 if (clicked_color != data->pd_Color)
840 struct RastPort *rp;
842 data->pd_Color = clicked_color;
844 if ((rp = ObtainGIRPort(msg->gpi_GInfo)))
846 DoMethod((Object *)g, GM_RENDER, (IPTR) msg->gpi_GInfo, (IPTR) rp, GREDRAW_UPDATE);
848 ReleaseGIRPort(rp);
852 retval = GMR_MEACTIVE;
854 } /* if (gadget activated is a result of user input) */
855 else
857 retval = GMR_NOREUSE;
860 } /* if (gadget isn't disabled) */
862 ReturnInt("Palette::GoActive", IPTR, retval);
865 /**********************************************************************************************/
867 IPTR GTPalette__GM_HANDLEINPUT(Class *cl, Object *o, struct gpInput *msg)
869 struct PaletteData *data = INST_DATA(cl, o);
870 struct InputEvent *ie = msg->gpi_IEvent;
871 IPTR retval = 0UL;
873 EnterFunc(bug("Palette::HandleInput\n"));
875 retval = GMR_MEACTIVE;
877 if (ie->ie_Class == IECLASS_RAWMOUSE)
879 WORD x = msg->gpi_Mouse.X + data->pd_GadgetBox.Left;
880 WORD y = msg->gpi_Mouse.Y + data->pd_GadgetBox.Top;
882 if (x <= data->pd_PaletteBox.Left) x = data->pd_PaletteBox.Left + 1;
883 if (y <= data->pd_PaletteBox.Top) y = data->pd_PaletteBox.Top + 1;
884 if (x >= data->pd_PaletteBox.Left + data->pd_PaletteBox.Width - 1)
885 x = data->pd_PaletteBox.Left + data->pd_PaletteBox.Width - 2;
886 if (y >= data->pd_PaletteBox.Top + data->pd_PaletteBox.Height - 1)
887 y = data->pd_PaletteBox.Top + data->pd_PaletteBox.Height - 2;
889 switch (ie->ie_Code)
891 case SELECTUP:
893 /* If the button was released outside the gadget, then
894 ** go back to old state --> no longer: stegerg
897 D(bug("IECLASS_RAWMOUSE: SELECTUP\n"));
899 #if 0
900 if (!InsidePalette(data, x, y))
902 struct RastPort *rp;
904 /* Left released outside of gadget area, go back
905 ** to old state
907 data->pd_Color = data->pd_ColorBackup;
908 D(bug("Left released outside gadget\n"));
910 if ((rp = ObtainGIRPort(msg->gpi_GInfo)))
912 DoMethod(o, GM_RENDER, msg->gpi_GInfo, rp, GREDRAW_UPDATE);
914 ReleaseGIRPort(rp);
917 else
919 #endif
921 D(bug("Left released inside gadget, color=%d\n", GetPalettePen(data, data->pd_Color)));
922 *(msg->gpi_Termination) = GetPalettePen(data, data->pd_Color);
923 retval = GMR_VERIFY;
925 #if 0
927 #endif
929 retval |= GMR_NOREUSE;
930 break;
933 case IECODE_NOBUTTON:
936 UBYTE over_color;
938 D(bug("IECLASS_POINTERPOS\n"));
940 if (InsidePalette(data, x, y))
943 over_color = ComputeColor(data, x, y);
945 if (over_color != data->pd_Color)
947 struct RastPort *rp;
949 data->pd_Color = over_color;
950 if ((rp = ObtainGIRPort(msg->gpi_GInfo)))
952 DoMethod(o, GM_RENDER, (IPTR) msg->gpi_GInfo, (IPTR) rp, GREDRAW_UPDATE);
954 ReleaseGIRPort(rp);
957 } /* if (mouse is over a different color) */
959 } /* if (mouse is over gadget) */
961 retval = GMR_MEACTIVE;
963 } break;
966 case MENUUP:
968 /* Right released on gadget, go back to old state */
970 struct RastPort *rp;
972 data->pd_Color = data->pd_ColorBackup;
973 D(bug("Right mouse pushed \n"));
975 if ((rp = ObtainGIRPort(msg->gpi_GInfo)))
977 DoMethod(o, GM_RENDER, (IPTR) msg->gpi_GInfo, (IPTR) rp, GREDRAW_UPDATE);
979 ReleaseGIRPort(rp);
982 retval = GMR_NOREUSE;
983 break;
987 } /* switch (ie->ie_Code) */
989 } /* if (mouse event) */
991 ReturnInt("Palette::HandleInput", IPTR, retval);
994 /**********************************************************************************************/
996 IPTR GTPalette__OM_SET(Class *cl, Object *o, struct opSet *msg)
998 IPTR retval = DoSuperMethodA(cl, o, (Msg)msg);
999 retval += (IPTR)palette_set(cl, o, msg);
1000 /* If we have been subclassed, OM_UPDATE should not cause a GM_RENDER
1001 *because it would circumvent the subclass from fully overriding it.
1002 *The check of cl == OCLASS(o) should fail if we have been
1003 *subclassed, and we have gotten here via DoSuperMethodA().
1005 if ( retval && ((msg->MethodID != OM_UPDATE) || (cl == OCLASS(o))) )
1007 struct GadgetInfo *gi = msg->ops_GInfo;
1009 if (gi)
1011 struct RastPort *rp = ObtainGIRPort(gi);
1013 if (rp)
1015 DoMethod(o,
1016 GM_RENDER,
1017 (IPTR) gi,
1018 (IPTR) rp,
1019 FindTagItem(GA_Disabled, msg->ops_AttrList) ? GREDRAW_REDRAW : GREDRAW_UPDATE
1022 ReleaseGIRPort(rp);
1024 } /* if */
1026 } /* if */
1028 } /* if */
1030 return retval;
1033 /**********************************************************************************************/