2 Copyright © 1995-2005, The AROS Development Team. All rights reserved.
5 Desc: Internal GadTools palette class.
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() */
32 #include <aros/debug.h>
34 #include "gadtools_intern.h"
36 /**********************************************************************************************/
41 #define HBORDER HSPACING
42 #define VBORDER VSPACING
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
;
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
)
86 if (data
->pd_ColorTable
)
87 pen
= data
->pd_ColorTable
[idx
];
89 pen
= idx
+ data
->pd_ColorOffset
;
94 /**********************************************************************************************/
96 STATIC UBYTE
Colors2Depth(UWORD numcolors
)
100 while ((1 << depth
) < numcolors
)
106 /**********************************************************************************************/
108 STATIC BOOL
InsidePalette(struct PaletteData
*data
, WORD x
, WORD y
)
117 /**********************************************************************************************/
119 STATIC UWORD
ComputeColor(struct PaletteData
*data
, WORD x
, WORD y
)
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
;
134 else if (color
>= data
->pd_NumColors
)
136 color
= data
->pd_NumColors
- 1;
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
;
150 register UWORD col
, row
;
151 struct IBox
*pbox
= &(data
->pd_PaletteBox
);
153 EnterFunc(bug("RenderPalette(data=%p, rp=%p)\n", data
, rp
));
157 colors_left
= data
->pd_NumColors
;
160 for (row
= data
->pd_NumRows
; row
; row
--)
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
,
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
,
197 struct IBox framebox
;
198 WORD left
, top
, right
, bottom
;
200 EnterFunc(bug("UpdateActiveColor(data=%p, dri=%p, rp=%p)\n",
203 SetAPen(rp
, dri
->dri_Pens
[BACKGROUNDPEN
]);
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 */
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
254 RectFill(rp
, left
, top
,
258 RectFill(rp
, right
- 1, top
,
262 RectFill(rp
, left
+ 2, top
,
266 RectFill(rp
, left
+ 2, bottom
- 1,
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",
294 left
= gadbox
->Left
; top
= gadbox
->Top
;
295 right
= left
+ gadbox
->Width
- 1; bottom
= top
+ gadbox
->Height
- 1;
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
},
307 data
->pd_Frame
= NewObjectA(NULL
, FRAMEICLASS
, frame_tags
);
312 struct TagItem frameset_tags
[] =
314 {IA_Width
, gadbox
->Width
},
315 {IA_Height
, gadbox
->Height
},
316 {IA_Recessed
, recessed
},
317 {IA_EdgesOnly
, edgesonly
},
321 SetAttrsA(data
->pd_Frame
, frameset_tags
);
324 (struct Image
*)data
->pd_Frame
,
332 ReturnVoid("RenderFrame");
335 /**********************************************************************************************/
337 STATIC IPTR
palette_set(Class
*cl
, Object
*o
, struct opSet
*msg
)
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
;
347 EnterFunc(bug("Palette::Set()\n"));
349 while ((tag
= NextTagItem(&tstate
)))
351 IPTR tidata
= tag
->ti_Data
;
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
));
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
));
377 case GTPA_ColorOffset
: /* [I] */
378 data
->pd_ColorOffset
= (UBYTE
)tidata
;
379 D(bug("ColorOffset initialized to %d\n", tidata
));
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
391 data
->pd_LabelPlace
= GV_LabelPlace_Left
;
394 case GTPA_IndicatorHeight
: /* [I] */
395 data
->pd_IndHeight
= (UWORD
)tidata
;
396 D(bug("Indicatorheight set to %d\n", tidata
));
399 case GA_LabelPlace
: /* [I] */
400 data
->pd_LabelPlace
= (LONG
)tidata
;
401 D(bug("Labelplace set to %d\n", tidata
));
403 labelplace_set
= TRUE
;
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
));
412 case GTPA_ColorTable
:
413 data
->pd_ColorTable
= (UBYTE
*)tidata
;
417 numcolorstag_found
= TRUE
;
419 data
->pd_NumColors
= (UWORD
)tidata
;
423 } /* switch (tag->ti_Tag) */
425 } /* for (each attr in attrlist) */
429 /* convert pen number to index */
431 if (data
->pd_ColorTable
)
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
)
446 data
->pd_Color
-= data
->pd_ColorOffset
;
449 } /* if (colortag_found) */
453 /* Check if the old selected fits into the new depth */
454 if (data
->pd_Color
> data
->pd_NumColors
- 1)
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
);
474 switch (msg
->opg_AttrID
)
477 case GTA_ChildGadgetKind
:
478 *(msg
->opg_Storage
) = PALETTE_KIND
;
483 *msg
->opg_Storage
= (IPTR
)GetPalettePen(data
, data
->pd_Color
);
486 case GTPA_ColorOffset
:
487 *msg
->opg_Storage
= (IPTR
)data
->pd_ColorOffset
;
490 case GTPA_ColorTable
:
491 *msg
->opg_Storage
= (IPTR
)data
->pd_ColorTable
;
495 retval
= DoSuperMethodA(cl
, o
, (Msg
)msg
);
502 /**********************************************************************************************/
504 IPTR
GTPalette__OM_NEW(Class
*cl
, Object
*o
, struct opSet
*msg
)
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
);
524 struct PaletteData
*data
= INST_DATA(cl
, o
);
526 /* Set some defaults */
527 data
->pd_NumColors
= 2;
528 data
->pd_ColorTable
= NULL
;
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
);
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"));
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
)
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);
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
;
644 rows
= pbox
->Height
/ pbox
->Width
;
650 D(bug("Biggest aspect: %d\n", *largest
));
654 smallest_so_far
= 0xFFFF;
656 factor1
= 1 << Colors2Depth(data
->pd_NumColors
);
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
)
672 smallest_so_far
= fault
;
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
;
714 struct IBox
*gbox
= &(data
->pd_GadgetBox
);
716 EnterFunc(bug("Palette::Render()\n"));
720 switch (msg
->gpr_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
);
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
);
763 } /* switch (redraw method) */
765 if (g
->Flags
& GFLG_DISABLED
)
767 DoDisabledPattern(rp
,
770 gbox
->Left
+ gbox
->Width
- 1,
771 gbox
->Top
+ gbox
->Height
- 1,
772 dri
->dri_Pens
[SHADOWPEN
],
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
);
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
);
820 EnterFunc(bug("Palette::GoActive()\n"));
821 if (g
->Flags
& GFLG_DISABLED
)
823 retval
= GMR_NOREUSE
;
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
)
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
);
852 retval
= GMR_MEACTIVE
;
854 } /* if (gadget activated is a result of user input) */
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
;
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;
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"));
900 if (!InsidePalette(data
, x
, y
))
904 /* Left released outside of gadget area, go back
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
);
921 D(bug("Left released inside gadget, color=%d\n", GetPalettePen(data
, data
->pd_Color
)));
922 *(msg
->gpi_Termination
) = GetPalettePen(data
, data
->pd_Color
);
929 retval
|= GMR_NOREUSE
;
933 case IECODE_NOBUTTON
:
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
)
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
);
957 } /* if (mouse is over a different color) */
959 } /* if (mouse is over gadget) */
961 retval
= GMR_MEACTIVE
;
968 /* Right released on gadget, go back to old state */
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
);
982 retval
= GMR_NOREUSE
;
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
;
1011 struct RastPort
*rp
= ObtainGIRPort(gi
);
1019 FindTagItem(GA_Disabled
, msg
->ops_AttrList
) ? GREDRAW_REDRAW
: GREDRAW_UPDATE
1033 /**********************************************************************************************/