Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / libs / icon / drawiconstate.c
blobe2f8af63333926dca405c3b37bb0b0e4f45ef9b0
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <aros/debug.h>
7 #include <workbench/icon.h>
8 #include <intuition/imageclass.h>
10 #include "icon_intern.h"
12 /* Define this in order to simulate LUT screen on hi- and truecolor displays.
13 Useful for debugging.
14 #define FORCE_LUT_ICONS */
16 /*****************************************************************************
18 NAME */
19 #include <proto/icon.h>
21 AROS_LH7(void, DrawIconStateA,
23 /* SYNOPSIS */
24 AROS_LHA(struct RastPort *, rp, A0),
25 AROS_LHA(struct DiskObject *, icon, A1),
26 AROS_LHA(STRPTR, label, A2),
27 AROS_LHA(LONG, leftEdge, D0),
28 AROS_LHA(LONG, topEdge, D1),
29 AROS_LHA(ULONG, state, D2),
30 AROS_LHA(struct TagItem *, tags, A3),
32 /* LOCATION */
33 struct IconBase *, IconBase, 27, Icon)
35 /* FUNCTION
36 Draw an icon like an image.
38 INPUTS
39 rp - rastport to draw into
40 icon - the icon
41 label - label string
42 leftEdge,
43 topEdge - drawing position
44 state - drawing state, see intuition/imageclass.h
46 RESULT
48 NOTES
49 Only very limited implemented.
51 EXAMPLE
53 BUGS
55 SEE ALSO
56 intuition/imageclass.h
58 INTERNALS
60 HISTORY
62 *****************************************************************************/
64 AROS_LIBFUNC_INIT
65 LONG wDelta,textTop,textLeft;
66 struct NativeIcon *ni;
67 struct Rectangle rect = { };
68 struct DrawInfo *DrawInfo;
69 BOOL EraseBackground;
70 BOOL Frameless;
71 BOOL Borderless;
72 BOOL selected = (state == IDS_SELECTED);
73 UWORD Pens[NUMDRIPENS];
74 UWORD Width, Height;
75 int i;
77 /* No GfxBase? No RastPort? Then we can't draw anything. */
78 if (!GfxBase || !rp)
79 return;
81 ni = GetNativeIcon(icon, LB(IconBase));
83 Frameless = GetTagData(ICONDRAWA_Frameless, IconBase->ib_Frameless || (ni && ni->ni_Frameless), tags);
84 Borderless = GetTagData(ICONDRAWA_Borderless, FALSE, tags);
85 EraseBackground = GetTagData(ICONDRAWA_EraseBackground, !(IconBase->ib_Frameless || (ni && ni->ni_Frameless)), tags);
86 DrawInfo = (struct DrawInfo *)GetTagData(ICONDRAWA_DrawInfo, (IPTR)NULL, tags);
88 for (i = 0; i < NUMDRIPENS; i++) {
89 if (DrawInfo && DrawInfo->dri_NumPens > i)
90 Pens[i] = DrawInfo->dri_Pens[i];
91 else
92 Pens[i] = ni->ni_Pens[i];
95 if (!Borderless) {
96 rect = IconBase->ib_EmbossRectangle;
97 if (!Frameless) {
98 EraseBackground = TRUE;
99 rect.MinX -= 1;
100 rect.MinY -= 1;
101 rect.MaxX += 1;
102 rect.MaxY += 1;
104 } else {
105 Frameless = TRUE;
108 wDelta = 0;
109 textTop = 0;
110 textLeft = 0;
112 if (ni && ni->ni_Screen) {
113 Width = ni->ni_Width;
114 Height = ni->ni_Height;
115 } else {
116 Width = icon->do_Gadget.Width;
117 Height = icon->do_Gadget.Height;
120 if (label != NULL) {
121 struct TextExtent extent;
122 LONG txtlen = strlen(label);
124 if (txtlen > IconBase->ib_MaxNameLength)
125 txtlen = IconBase->ib_MaxNameLength;
127 wDelta = Width + (rect.MaxX - rect.MinX);
128 textTop = Height + (rect.MaxY - rect.MinY);
130 TextExtent(rp, label, txtlen, &extent);
132 /* wDelta will be the centering offset for the icon */
133 /* textLeft is the horiz offset for the text */
135 if (extent.te_Width > wDelta) {
136 wDelta = (extent.te_Width - wDelta) / 2;
137 textLeft = 0;
138 } else {
139 textLeft = (wDelta - extent.te_Width) / 2;
140 wDelta = 0;
143 SetAPen(rp, Pens[FILLTEXTPEN]);
144 SetOutlinePen(rp, selected ? Pens[HIGHLIGHTTEXTPEN] : Pens[TEXTPEN]);
145 SetBPen(rp, Pens[BACKGROUNDPEN]);
147 Move(rp, leftEdge + textLeft, topEdge + textTop - extent.te_Extent.MinY);
148 Text(rp, label, txtlen);
151 topEdge -= rect.MinY;
152 leftEdge -= rect.MinX;
154 leftEdge += wDelta;
156 if (EraseBackground) {
157 SetAPen(rp, Pens[BACKGROUNDPEN]);
158 RectFill(rp, leftEdge + rect.MinX, topEdge + rect.MinY,
159 leftEdge + Width + rect.MaxX - 1, topEdge + Height + rect.MaxY - 1);
162 D(bug("[%s] Render %ldx%ld icon %p at %ldx%ld\n", __func__, Width, Height, icon, leftEdge, topEdge));
164 if (ni)
166 struct NativeIconImage *image;
167 int id;
168 struct BitMap *bm;
169 PLANEPTR mask;
171 id = selected ? 1 : 0;
172 image = &ni->ni_Image[id];
174 if (image->ARGBMap) {
175 WritePixelArrayAlpha(image->ARGBMap, 0, 0, ni->ni_Width * sizeof(ULONG),
176 rp, leftEdge, topEdge,
177 ni->ni_Width, ni->ni_Height, 0);
178 goto emboss;
181 /* If we don't have selected bitmap,
182 * use the normal bitmap
184 bm = image->BitMap;
185 mask = image->BitMask;
186 if (bm == NULL) {
187 bm = ni->ni_Image[0].BitMap;
188 mask = ni->ni_Image[0].BitMask;
190 #ifdef __mc68000 /* AGA support */
191 /* Get the 64 bit aligned mask */
192 mask = (APTR)(((IPTR)mask + 7) & ~7);
193 #endif
195 /* Planar maps */
196 if (bm)
198 #if DEBUG
199 int i;
201 bug("[%s] Using Bitmap: 0x%p, BitMask 0x%p\n", __func__, bm, mask);
202 for (i = 0; i < bm->Depth; i++)
203 bug("[%s] Planes[%d] = %p\n", __func__, i, bm->Planes[i]);
204 #endif
206 if (mask) {
207 BltMaskBitMapRastPort(bm, 0, 0,
208 rp, leftEdge, topEdge,
209 Width, Height, ABC|ABNC|ANBC, mask);
210 } else {
211 BltBitMapRastPort(bm, 0, 0,
212 rp, leftEdge, topEdge,
213 Width, Height, ABC|ABNC);
215 goto emboss;
219 /* Uh. No layout? Just draw a square.
221 D(bug("[Icon] No image present\n"));
222 SetAPen(rp, selected ? Pens[SHINEPEN] : Pens[SHADOWPEN]);
223 RectFill(rp, leftEdge, topEdge,
224 leftEdge + Width - 1,
225 topEdge + Height - 1);
227 emboss:
228 /* Draw the 3D border */
229 if (!Frameless) {
230 D(bug("[Icon] Embossing\n"));
232 rect.MinX += leftEdge;
233 rect.MaxX += leftEdge + Width - 1;
234 rect.MinY += topEdge;
235 rect.MaxY += topEdge + Height - 1;
237 /* Draw the left and top lines */
238 SetAPen(rp, selected ? Pens[SHADOWPEN] : Pens[SHINEPEN]);
239 Move(rp, rect.MinX, rect.MaxY - 1);
240 Draw(rp, rect.MinX, rect.MinY);
241 Draw(rp, rect.MaxX - 1, rect.MinY);
243 /* Draw the right and bottom lines */
244 SetAPen(rp, selected ? Pens[SHINEPEN] : Pens[SHADOWPEN]);
245 Move(rp, rect.MaxX, rect.MinY + 1);
246 Draw(rp, rect.MaxX, rect.MaxY);
247 Draw(rp, rect.MinX + 1, rect.MaxY);
249 SetAPen(rp, Pens[BACKGROUNDPEN]);
250 WritePixel(rp, rect.MinX, rect.MaxY);
251 WritePixel(rp, rect.MaxX, rect.MinY);
255 AROS_LIBFUNC_EXIT
256 } /* DrawIconStateA() */