2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
5 Desc: Support functions for the palette class
11 #include <proto/graphics.h>
12 #include <proto/intuition.h>
13 #include <graphics/gfxmacros.h>
14 #include <intuition/classes.h>
15 #include <intuition/cghooks.h>
16 #include <intuition/gadgetclass.h>
17 #include <intuition/imageclass.h>
18 #include <intuition/screens.h>
19 #include <intuition/intuition.h>
21 #include "arospalette_intern.h"
25 #include <aros/debug.h>
27 /**********************
29 **********************/
31 VOID
GetGadgetIBox(Object
*o
, struct GadgetInfo
*gi
, struct IBox
*ibox
)
33 ibox
->Left
= EG(o
)->LeftEdge
;
34 ibox
->Top
= EG(o
)->TopEdge
;
35 ibox
->Width
= EG(o
)->Width
;
36 ibox
->Height
= EG(o
)->Height
;
40 if (EG(o
)->Flags
& GFLG_RELRIGHT
)
41 ibox
->Left
+= gi
->gi_Domain
.Width
- 1;
43 if (EG(o
)->Flags
& GFLG_RELBOTTOM
)
44 ibox
->Top
+= gi
->gi_Domain
.Height
- 1;
46 if (EG(o
)->Flags
& GFLG_RELWIDTH
)
47 ibox
->Width
+= gi
->gi_Domain
.Width
;
49 if (EG(o
)->Flags
& GFLG_RELHEIGHT
)
50 ibox
->Height
+= gi
->gi_Domain
.Height
;
55 /**********************
57 **********************/
59 UWORD
GetPalettePen(struct PaletteData
*data
, UWORD idx
)
63 if (data
->pd_ColorTable
)
64 pen
= data
->pd_ColorTable
[idx
];
66 pen
= idx
+ data
->pd_ColorOffset
;
72 /*********************
74 *********************/
76 UBYTE
Colors2Depth(UWORD numcolors
)
80 while ((1 << depth
) < numcolors
)
91 BOOL
InsidePalette(struct PaletteData
*data
, WORD x
, WORD y
)
99 struct IBox
*pbox
= &(data
->pd_PaletteBox
);
101 /* Inside palette bounding box ? */
103 if ( (x
> pbox
->Left
)
104 && (x
< pbox
->Left
+ pbox
->Width
- 1)
106 && (y
< pbox
->Top
+ pbox
->Height
- 1)
109 /* Must do additional testing, since we might
110 ** not have 2^n number of colors
113 if (data
->pd_NumColors
> ComputeColor(data
, x
, y
))
124 /*********************
126 *********************/
128 UWORD
ComputeColor(struct PaletteData
*data
, WORD x
, WORD y
)
134 col
= (x
- data
->pd_PaletteBox
.Left
) / data
->pd_ColWidth
;
135 row
= (y
- data
->pd_PaletteBox
.Top
) / data
->pd_RowHeight
;
137 color
= data
->pd_NumCols
* row
+ col
;
143 else if (color
>= data
->pd_NumColors
)
145 color
= data
->pd_NumColors
- 1;
152 /********************
154 ********************/
156 #define MIN(a, b) (( a < b) ? a : b)
157 VOID
RenderPalette(struct PaletteData
*data
, struct RastPort
*rp
,
158 struct PaletteBase_intern
*AROSPaletteBase
)
160 UWORD currentcolor
= data
->pd_ColorOffset
, colors_left
;
162 register UWORD col
, row
;
163 struct IBox
*pbox
= &(data
->pd_PaletteBox
);
165 EnterFunc(bug("RenderPalette(data=%p, rp=%p)\n", data
, rp
));
169 colors_left
= data
->pd_NumColors
;
172 for (row
= data
->pd_NumRows
; row
; row
--)
175 for (col
= MIN(data
->pd_NumCols
, colors_left
); col
; col
--)
178 SetAPen(rp
, GetPalettePen(data
, currentcolor
));
180 RectFill(rp
, left
, top
,
181 left
+ data
->pd_ColWidth
- VSPACING
- 1,
182 top
+ data
->pd_RowHeight
- HSPACING
- 1 );
184 D(bug("Rectfilling area (%d, %d, %d, %d)\n with color %d", left
, top
,
185 left
+ data
->pd_ColWidth
- VSPACING
- 1, top
+ data
->pd_RowHeight
- HSPACING
,
190 left
+= data
->pd_ColWidth
;
192 } /* for (each row) */
193 top
+= data
->pd_RowHeight
;
195 colors_left
-= data
->pd_NumCols
;
197 } /* for (each column) */
199 ReturnVoid("RenderPalette");
203 /************************
204 ** UpdateActiveColor **
205 ************************/
207 VOID
UpdateActiveColor( struct PaletteData
*data
,
208 struct DrawInfo
*dri
,
210 struct PaletteBase_intern
*AROSPaletteBase
)
213 WORD left
, top
, right
, bottom
;
215 struct IBox framebox
;
217 EnterFunc(bug("UpdateActiveColor(data=%p, dri=%p, rp=%p)\n",
220 SetAPen(rp
, dri
->dri_Pens
[BACKGROUNDPEN
]);
223 if (data
->pd_OldColor
!= data
->pd_Color
)
226 left
= data
->pd_PaletteBox
.Left
+ (data
->pd_OldColor
% data
->pd_NumCols
) * data
->pd_ColWidth
;
227 top
= data
->pd_PaletteBox
.Top
+ (data
->pd_OldColor
/ data
->pd_NumCols
) * data
->pd_RowHeight
;
229 D(bug("clearing old selected: (%d, %d, %d, %d) oldcolor=%d\n",
230 left
, top
, left
+ data
->pd_ColWidth
, top
+ data
->pd_RowHeight
, data
->pd_OldColor
));
232 /* Clear area with BACKGROUNDPEN */
236 left
+ data
->pd_ColWidth
- 1,
237 top
+ data
->pd_RowHeight
- 1);
239 /* Rerender in original color */
240 SetAPen(rp
, GetPalettePen(data
, data
->pd_OldColor
+ data
->pd_ColorOffset
));
242 RectFill(rp
, left
, top
,
243 left
+ data
->pd_ColWidth
- VSPACING
- 1,
244 top
+ data
->pd_RowHeight
- HSPACING
- 1);
248 left
= data
->pd_PaletteBox
.Left
+ (data
->pd_Color
% data
->pd_NumCols
) * data
->pd_ColWidth
;
249 top
= data
->pd_PaletteBox
.Top
+ (data
->pd_Color
/ data
->pd_NumCols
) * data
->pd_RowHeight
;
251 /* Right & bottom of *colored* area */
252 right
= left
+ data
->pd_ColWidth
- VSPACING
- 1;
253 bottom
= top
+ data
->pd_RowHeight
- HSPACING
- 1;
255 /* Render new active entry */
256 D(bug("rendering new selected: (%d, %d, %d, %d), color=%d\n",
257 left
, top
, right
, bottom
, data
->pd_Color
));
260 if ((right
- left
>= 6) && (bottom
- top
>= 6))
262 /* Draw some borders */
264 SetAPen(rp
, dri
->dri_Pens
[BACKGROUNDPEN
]);
266 /* We draw left & right from top to bottom, but draw top & bottom
267 ** so they don't overlap with what's allready drawn
271 RectFill(rp
, left
, top
,
275 RectFill(rp
, right
- 1, top
,
279 RectFill(rp
, left
+ 2, top
,
283 RectFill(rp
, left
+ 2, bottom
- 1,
287 /* Draw recessed frame around selected color */
288 framebox
.Left
= left
- VBORDER
;
289 framebox
.Top
= top
- HBORDER
;
290 framebox
.Width
= data
->pd_ColWidth
+ VBORDER
;
291 framebox
.Height
= data
->pd_RowHeight
+ HBORDER
;
293 RenderFrame(data
, rp
, &framebox
, dri
, TRUE
, TRUE
, AROSPaletteBase
);
295 /* The newly update color becomes the new OldColor */
296 data
->pd_OldColor
= data
->pd_Color
;
298 ReturnVoid("UpdateActiveColor");
302 /****************************
303 ** DrawDisabledPattern() **
304 ****************************/
306 /* draws a disabled pattern */
307 void DrawDisabledPattern(struct RastPort
*rport
, struct IBox
*gadbox
, UWORD pen
,
308 struct PaletteBase_intern
*AROSPaletteBase
)
310 UWORD pattern
[] = { 0x8888, 0x2222 };
312 EnterFunc(bug("DrawDisabledPattern(rp=%p, gadbox=%p, pen=%d)\n",
313 rport
, gadbox
, pen
));
315 SetDrMd( rport
, JAM1
);
316 SetAPen( rport
, pen
);
317 SetAfPt( rport
, pattern
, 1);
319 /* render disable pattern */
320 RectFill( rport
, gadbox
->Left
,
322 gadbox
->Left
+ gadbox
->Width
- 1,
323 gadbox
->Top
+ gadbox
->Height
-1 );
325 SetAfPt ( rport
, NULL
, 0);
327 ReturnVoid("DrawDisabledPattern");
334 struct TextFont
*PrepareFont(struct RastPort
*rport
, struct IntuiText
*itext
,
335 struct TextFont
**oldfont
,
336 struct PaletteBase_intern
*AROSPaletteBase
)
338 struct TextFont
*font
;
340 EnterFunc(bug("PrepareFont(rp=%p, itext=%p)\n", rport
, itext
));
342 if (itext
->ITextFont
)
344 *oldfont
= rport
->Font
;
345 font
= OpenFont(itext
->ITextFont
);
348 SetFont(rport
, font
);
349 SetSoftStyle(rport
, itext
->ITextFont
->ta_Style
, 0xffffffff);
357 SetABPenDrMd(rport
, itext
->FrontPen
, itext
->BackPen
, itext
->DrawMode
);
359 ReturnPtr("PrepareFont", struct TextFont
*, font
);
363 /********************
365 ********************/
366 void DisposeFont(struct RastPort
*rport
,
367 struct TextFont
*font
, struct TextFont
*oldfont
,
368 struct PaletteBase_intern
*AROSPaletteBase
)
370 EnterFunc(bug("DisposeFont(rp=%p, font=%p, oldofnt=%p)\n",
371 rport
, font
, oldfont
));
374 SetFont(rport
, oldfont
);
378 ReturnVoid("DisposeFont");
382 /********************
384 ********************/
385 BOOL
RenderLabel( struct Gadget
*gad
, struct IBox
*gadbox
,
386 struct RastPort
*rport
, LONG labelplace
,
387 struct PaletteBase_intern
*AROSPaletteBase
)
389 struct TextFont
*font
= NULL
, *oldfont
;
390 struct TextExtent te
;
395 EnterFunc(bug("RenderLabel(gad=%p, gadbox=%p, rp=%p, labelplace=%ld)\n",
396 gad
, gadbox
, rport
, labelplace
));
400 /* Calculate offsets. */
401 if ((gad
->Flags
& GFLG_LABELSTRING
))
402 text
= (STRPTR
)gad
->GadgetText
;
403 else if ((gad
->Flags
& GFLG_LABELIMAGE
))
407 /* GFLG_LABELITEXT */
408 text
= gad
->GadgetText
->IText
;
409 font
= PrepareFont(rport
, gad
->GadgetText
, &oldfont
, AROSPaletteBase
);
417 TextExtent(rport
, text
, len
, &te
);
419 height
= te
.te_Height
;
423 width
= ((struct Image
*)gad
->GadgetText
)->Width
;
424 height
= ((struct Image
*)gad
->GadgetText
)->Height
;
427 if (labelplace
== GV_LabelPlace_Right
)
429 x
= gadbox
->Left
+ gadbox
->Width
+ 5;
430 y
= gadbox
->Top
+ (gadbox
->Height
- height
) / 2 + 1;
432 else if (labelplace
== GV_LabelPlace_Above
)
434 x
= gadbox
->Left
- (width
- gadbox
->Width
) / 2;
435 y
= gadbox
->Top
- height
- 2;
437 else if (labelplace
== GV_LabelPlace_Below
)
439 x
= gadbox
->Left
- (width
- gadbox
->Width
) / 2;
440 y
= gadbox
->Top
+ gadbox
->Height
+ 3;
442 else if (labelplace
== GV_LabelPlace_In
)
444 x
= gadbox
->Left
- (width
- gadbox
->Width
) / 2;
445 y
= gadbox
->Top
+ (gadbox
->Height
- height
) / 2 + 1;
447 else /* GV_LabelPlace_Left */
449 x
= gadbox
->Left
- width
- 4;
450 y
= gadbox
->Top
+ (gadbox
->Height
- height
) / 2 + 1;
453 if (gad
->Flags
& GFLG_LABELSTRING
)
455 SetABPenDrMd(rport
, 1, 0, JAM1
);
457 Text(rport
, text
, len
);
459 else if (gad
->Flags
& GFLG_LABELIMAGE
)
460 DrawImage(rport
, (struct Image
*)gad
->GadgetText
, x
, y
);
463 PrintIText(rport
, gad
->GadgetText
, x
, y
);
464 DisposeFont(rport
, font
, oldfont
, AROSPaletteBase
);
467 ReturnBool("RenderLabel", TRUE
);
471 /********************
473 ********************/
474 VOID
RenderFrame(struct PaletteData
*data
, struct RastPort
*rp
, struct IBox
*gadbox
,
475 struct DrawInfo
*dri
, BOOL recessed
, BOOL edgesonly
, struct PaletteBase_intern
*AROSPaletteBase
)
479 EnterFunc(bug("RenderFrame(rp=%p, gadbox=%p, dri=%p)\n",
482 left
= gadbox
->Left
; top
= gadbox
->Top
;
486 struct TagItem frame_tags
[] =
488 {IA_Resolution
, (dri
->dri_Resolution
.X
<< 16) + dri
->dri_Resolution
.Y
},
489 {IA_FrameType
, FRAME_BUTTON
},
490 {IA_EdgesOnly
, edgesonly
},
494 data
->pd_Frame
= NewObjectA(NULL
, FRAMEICLASS
, frame_tags
);
499 struct TagItem frameset_tags
[] =
501 {IA_Width
, gadbox
->Width
},
502 {IA_Height
, gadbox
->Height
},
503 {IA_Recessed
, recessed
},
504 {IA_EdgesOnly
, edgesonly
},
508 SetAttrsA(data
->pd_Frame
, frameset_tags
);
511 (struct Image
*)data
->pd_Frame
,
519 ReturnVoid("RenderFrame");