revert between 56095 -> 55830 in arch
[AROS.git] / workbench / classes / gadgets / arospalette / support.c
blobdae991b97c25bb610e622ff9bee9da6eda9c328f
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Support functions for the palette class
6 Lang: English
7 */
9 #include <string.h>
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"
23 #define SDEBUG 0
24 #define DEBUG 0
25 #include <aros/debug.h>
27 /**********************
28 ** GetGadgetIBox() **
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;
38 if (gi)
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 /**********************
56 ** GetPalettePen() **
57 **********************/
59 UWORD GetPalettePen(struct PaletteData *data, UWORD idx)
61 UWORD pen;
63 if (data->pd_ColorTable)
64 pen = data->pd_ColorTable[idx];
65 else
66 pen = idx + data->pd_ColorOffset;
68 return (pen);
72 /*********************
73 ** Colors2Depth() **
74 *********************/
76 UBYTE Colors2Depth(UWORD numcolors)
78 UBYTE depth = 0;
80 while ((1 << depth) < numcolors)
81 depth ++;
83 return (depth);
87 /********************
88 ** InsidePalette **
89 ********************/
91 BOOL InsidePalette(struct PaletteData *data, WORD x, WORD y)
93 /* stegerg */
95 return TRUE;
97 #if 0
98 BOOL inside = FALSE;
99 struct IBox *pbox = &(data->pd_PaletteBox);
101 /* Inside palette bounding box ? */
103 if ( (x > pbox->Left)
104 && (x < pbox->Left + pbox->Width - 1)
105 && (y > pbox->Top)
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))
115 inside = TRUE;
118 return (inside);
119 #endif
124 /*********************
125 ** ComputeColor() **
126 *********************/
128 UWORD ComputeColor(struct PaletteData *data, WORD x, WORD y)
130 UWORD row, col;
132 WORD color;
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;
139 if (color < 0)
141 color = 0;
143 else if (color >= data->pd_NumColors)
145 color = data->pd_NumColors - 1;
148 return (UWORD)color;
152 /********************
153 ** RenderPalette **
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;
161 WORD left, top;
162 register UWORD col, row;
163 struct IBox *pbox = &(data->pd_PaletteBox);
165 EnterFunc(bug("RenderPalette(data=%p, rp=%p)\n", data, rp));
167 top = pbox->Top;
169 colors_left = data->pd_NumColors;
170 SetDrMd(rp, JAM1);
172 for (row = data->pd_NumRows; row; row --)
174 left = pbox->Left;
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,
186 currentcolor));
188 currentcolor ++;
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,
209 struct RastPort *rp,
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",
218 data, dri, rp));
220 SetAPen(rp, dri->dri_Pens[BACKGROUNDPEN]);
221 SetDrMd(rp, JAM1);
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 */
233 RectFill(rp,
234 left - VBORDER,
235 top - HBORDER,
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
270 /* left */
271 RectFill(rp, left, top,
272 left + 1, bottom);
274 /* right */
275 RectFill(rp, right - 1, top,
276 right, bottom);
278 /* top */
279 RectFill(rp, left + 2, top,
280 right - 2, top + 1);
282 /* bottom */
283 RectFill(rp, left + 2, bottom - 1,
284 right - 2, bottom);
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,
321 gadbox->Top,
322 gadbox->Left + gadbox->Width - 1,
323 gadbox->Top + gadbox->Height -1 );
325 SetAfPt ( rport, NULL, 0);
327 ReturnVoid("DrawDisabledPattern");
331 /******************
332 ** PrepareFont **
333 ******************/
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);
346 if (font)
348 SetFont(rport, font);
349 SetSoftStyle(rport, itext->ITextFont->ta_Style, 0xffffffff);
350 } else
351 font = rport->Font;
352 } else
354 *oldfont = NULL;
355 font = rport->Font;
357 SetABPenDrMd(rport, itext->FrontPen, itext->BackPen, itext->DrawMode);
359 ReturnPtr("PrepareFont", struct TextFont *, font);
363 /********************
364 ** DisposeFont() **
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));
372 if (oldfont)
374 SetFont(rport, oldfont);
375 CloseFont(font);
378 ReturnVoid("DisposeFont");
382 /********************
383 ** RenderLabel() **
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;
391 STRPTR text;
392 int len = 0, x, y;
393 UWORD width, height;
395 EnterFunc(bug("RenderLabel(gad=%p, gadbox=%p, rp=%p, labelplace=%ld)\n",
396 gad, gadbox, rport, labelplace));
398 if (gad->GadgetText)
400 /* Calculate offsets. */
401 if ((gad->Flags & GFLG_LABELSTRING))
402 text = (STRPTR)gad->GadgetText;
403 else if ((gad->Flags & GFLG_LABELIMAGE))
404 text = NULL;
405 else
407 /* GFLG_LABELITEXT */
408 text = gad->GadgetText->IText;
409 font = PrepareFont(rport, gad->GadgetText, &oldfont, AROSPaletteBase);
410 if (!font)
411 return FALSE;
414 if (text)
416 len = strlen(text);
417 TextExtent(rport, text, len, &te);
418 width = te.te_Width;
419 height = te.te_Height;
421 else
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);
456 Move(rport, x, y);
457 Text(rport, text, len);
459 else if (gad->Flags & GFLG_LABELIMAGE)
460 DrawImage(rport, (struct Image *)gad->GadgetText, x, y);
461 else
463 PrintIText(rport, gad->GadgetText, x, y);
464 DisposeFont(rport, font, oldfont, AROSPaletteBase);
467 ReturnBool("RenderLabel", TRUE);
471 /********************
472 ** RenderFrame() **
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)
477 WORD left, top;
479 EnterFunc(bug("RenderFrame(rp=%p, gadbox=%p, dri=%p)\n",
480 rp, gadbox, dri));
482 left = gadbox->Left; top = gadbox->Top;
484 if (!data->pd_Frame)
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 },
491 {TAG_DONE }
494 data->pd_Frame = NewObjectA(NULL, FRAMEICLASS, frame_tags);
497 if (data->pd_Frame)
499 struct TagItem frameset_tags[] =
501 {IA_Width , gadbox->Width },
502 {IA_Height , gadbox->Height },
503 {IA_Recessed , recessed },
504 {IA_EdgesOnly , edgesonly },
505 {TAG_DONE }
508 SetAttrsA(data->pd_Frame, frameset_tags);
510 DrawImageState(rp,
511 (struct Image *)data->pd_Frame,
512 left,
513 top,
514 IDS_NORMAL,
515 dri);
519 ReturnVoid("RenderFrame");