New bitmap method SetRGBConversionFunction which can be used to
[tangerine.git] / rom / intuition / scrdecorclass.c
bloba3c279af4305ba273e6ba91b67418a530ff8fc1e
1 /*
2 Copyright © 1995-2005, The AROS Development Team. All rights reserved.
3 Copyright © 2001-2003, The MorphOS Development Team. All Rights Reserved.
4 $Id: imageclass.c 20651 2004-01-17 20:57:12Z chodorowski $
5 */
8 #include <dos/dos.h>
9 #include <dos/dosextens.h>
11 #include <intuition/intuition.h>
12 #include <intuition/intuitionbase.h>
13 #include <intuition/classes.h>
14 #include <intuition/classusr.h>
15 #include <intuition/scrdecorclass.h>
16 #include <intuition/cghooks.h>
17 #include <intuition/icclass.h>
18 #include <intuition/extensions.h>
20 #include <graphics/gfxbase.h>
21 #include <graphics/gfxmacros.h>
23 #include <utility/tagitem.h>
24 #include <utility/hooks.h>
26 #include <clib/macros.h>
28 #include <string.h>
30 #include <proto/exec.h>
31 #include <proto/intuition.h>
32 #include <proto/graphics.h>
33 #include <proto/utility.h>
35 #include <proto/alib.h>
37 #include "intuition_intern.h"
38 #include "gadgets.h"
40 /**************************************************************************************************/
42 #ifdef __AROS__
43 #define USE_AROS_DEFSIZE 1
44 #else
45 #define USE_AROS_DEFSIZE 0
46 #endif
48 #define DEFSIZE_WIDTH 14
49 #define DEFSIZE_HEIGHT 14
51 #define HSPACING 3
52 #define VSPACING 3
53 /* Ralph Schmidt
54 * heuristics for smaller arrows used in apps
55 * like filer
57 #define HSPACING_MIDDLE 2
58 #define VSPACING_MIDDLE 2
59 #define HSPACING_SMALL 1
60 #define VSPACING_SMALL 1
62 #define DRI(dri) ((struct DrawInfo *)(dri))
64 /**************************************************************************************************/
66 static void renderimageframe(struct RastPort *rp, ULONG which, ULONG state, UWORD *pens,
67 WORD left, WORD top, WORD width, WORD height,
68 struct IntuitionBase *IntuitionBase)
70 WORD right = left + width - 1;
71 WORD bottom = top + height - 1;
72 BOOL leftedgegodown = FALSE;
73 BOOL topedgegoright = FALSE;
75 if (left == 0) leftedgegodown = TRUE;
76 if (top == 0) topedgegoright = TRUE;
78 SetAPen(rp, pens[((state == IDS_SELECTED) || (state == IDS_INACTIVESELECTED)) ? SHADOWPEN : SHINEPEN]);
80 /* left edge */
81 RectFill(rp, left,
82 top,
83 left,
84 bottom - (leftedgegodown ? 0 : 1));
86 /* top edge */
87 RectFill(rp, left + 1,
88 top,
89 right - (topedgegoright ? 0 : 1),
90 top);
92 SetAPen(rp, pens[((state == IDS_SELECTED) || (state == IDS_INACTIVESELECTED)) ? SHINEPEN : SHADOWPEN]);
94 /* right edge */
95 RectFill(rp, right,
96 top + (topedgegoright ? 1 : 0),
97 right,
98 bottom);
100 /* bottom edge */
101 RectFill(rp, left + (leftedgegodown ? 1 : 0),
102 bottom,
103 right - 1,
104 bottom);
107 /**************************************************************************************************/
109 static UWORD getbgpen(ULONG state, UWORD *pens)
111 UWORD bg;
113 switch (state)
115 case IDS_NORMAL:
116 case IDS_SELECTED:
117 bg = pens[FILLPEN];
118 break;
120 default:
121 bg = pens[BACKGROUNDPEN];
122 break;
125 return bg;
129 /**************************************************************************************************/
131 #undef IntuitionBase
132 #define IntuitionBase ((struct IntuitionBase *)(cl->cl_UserData))
134 /**************************************************************************************************/
136 IPTR ScrDecorClass__OM_NEW(Class *cl, Object *obj, struct opSet *msg)
138 struct scrdecor_data *data;
140 obj = (Object *)DoSuperMethodA(cl, obj, (Msg)msg);
141 if (obj)
143 data = INST_DATA(cl, obj);
145 data->dri = (struct IntDrawInfo *)GetTagData(SDA_DrawInfo, 0, msg->ops_AttrList);
146 data->scr = (struct Screen *)GetTagData(SDA_Screen, 0, msg->ops_AttrList);
148 if (!data->dri || !data->scr)
150 STACKULONG method = OM_DISPOSE;
152 CoerceMethodA(cl, obj, (Msg)&method);
154 return 0;
159 return (IPTR)obj;
162 /**************************************************************************************************/
164 IPTR ScrDecorClass__OM_GET(Class *cl, Object *obj, struct opGet *msg)
166 struct scrdecor_data *data = INST_DATA(cl, obj);
168 switch(msg->opg_AttrID)
170 case SDA_DrawInfo:
171 *msg->opg_Storage = (IPTR)data->dri;
172 break;
174 case SDA_Screen:
175 *msg->opg_Storage = (IPTR)data->scr;
176 break;
178 case SDA_TrueColorOnly:
179 *msg->opg_Storage = FALSE;
180 break;
182 default:
183 return DoSuperMethodA(cl, obj, (Msg)msg);
186 return 1;
190 /**************************************************************************************************/
192 IPTR ScrDecorClass__SDM_GETDEFSIZE_SYSIMAGE(Class *cl, Object *obj, struct sdpGetDefSizeSysImage *msg)
194 ULONG def_low_width = DEFSIZE_WIDTH, def_low_height = DEFSIZE_HEIGHT;
195 ULONG def_med_width = DEFSIZE_WIDTH, def_med_height = DEFSIZE_HEIGHT;
196 ULONG def_high_width = DEFSIZE_WIDTH, def_high_height = DEFSIZE_HEIGHT;
198 switch(msg->sdp_Which)
200 case SDEPTHIMAGE:
201 #if USE_AROS_DEFSIZE
202 def_low_width = def_med_width = def_high_width = DEFSIZE_WIDTH;
203 def_low_height = def_med_height = def_high_height = DEFSIZE_HEIGHT;
204 #else
205 def_low_width = 17;
206 def_med_width = 23;
207 def_high_width = 23;
208 #endif
209 break;
211 default:
212 return FALSE;
215 switch(msg->sdp_SysiSize)
217 case SYSISIZE_LOWRES:
218 *msg->sdp_Width = def_low_width;
219 *msg->sdp_Height = def_low_height;
220 break;
222 case SYSISIZE_MEDRES:
223 *msg->sdp_Width = def_med_width;
224 *msg->sdp_Height = def_med_height;
225 break;
227 case SYSISIZE_HIRES:
228 default:
229 *msg->sdp_Width = def_high_width;
230 *msg->sdp_Height = def_high_height;
231 break;
234 return TRUE;
237 /**************************************************************************************************/
239 IPTR ScrDecorClass__SDM_DRAW_SYSIMAGE(Class *cl, Object *obj, struct sdpDrawSysImage *msg)
241 struct scrdecor_data *data = INST_DATA(cl, obj);
242 struct RastPort *rp = msg->sdp_RPort;
243 UWORD *pens = DRI(data->dri)->dri_Pens;
244 LONG state = msg->sdp_State;
245 LONG left = msg->sdp_X;
246 LONG top = msg->sdp_Y;
247 LONG width = msg->sdp_Width;
248 LONG height = msg->sdp_Height;
249 LONG right = left + width - 1;
250 LONG bottom = top + height - 1;
252 SetDrMd(rp, JAM1);
254 switch(msg->sdp_Which)
256 case SDEPTHIMAGE:
258 UWORD bg;
259 WORD h_spacing;
260 WORD v_spacing;
262 renderimageframe(rp, DEPTHIMAGE, state, pens,
263 left, top, width, height, IntuitionBase);
264 left++;
265 top++;
266 right--;
267 bottom--;
268 width -= 2;
269 height -= 2;
271 h_spacing = width / 6;
272 v_spacing = height / 6;
274 bg = pens[BACKGROUNDPEN];
276 /* Clear background into correct color */
277 SetAPen(rp, bg);
278 RectFill(rp, left, top, right, bottom);
280 /* Draw a image of two partly overlapped tiny windows,
283 left += h_spacing;
284 top += v_spacing;
286 width -= h_spacing * 2;
287 height -= v_spacing * 2;
289 right = left + width - 1;
290 bottom = top + height - 1;
292 /* Render top left window */
294 SetAPen(rp, pens[SHADOWPEN]);
295 drawrect(rp, left, top, right - (width / 3 ), bottom - (height / 3), IntuitionBase);
297 /* Render bottom right window */
298 SetAPen(rp, pens[SHADOWPEN]);
299 drawrect(rp, left + (width / 3), top + (height / 3), right, bottom, IntuitionBase);
301 /* Fill bottom right window (inside of the frame above) */
302 SetAPen(rp, pens[SHINEPEN]);
303 RectFill(rp, left + (width / 3) + 1, top + (height / 3) + 1,
304 right - 1, bottom - 1);
307 if (state == IDS_SELECTED)
309 /* Re-Render top left window */
311 SetAPen(rp, pens[SHADOWPEN]);
312 drawrect(rp, left, top, right - (width / 3 ), bottom - (height / 3), IntuitionBase);
314 break;
317 default:
318 return FALSE;
321 return TRUE;
324 /**************************************************************************************************/
326 static void findtitlearea(struct Screen *scr, LONG *left, LONG *right)
328 struct Gadget *g;
330 *left = 0;
331 *right = scr->Width - 1;
333 for (g = scr->FirstGadget; g; g = g->NextGadget)
335 if (!(g->Flags & GFLG_RELRIGHT))
337 if (g->LeftEdge + g->Width > *left)
338 *left = g->LeftEdge + g->Width;
340 else
342 if (g->LeftEdge + scr->Width - 1 - 1 < *right)
343 *right = g->LeftEdge + scr->Width - 1 - 1;
349 /**************************************************************************************************/
351 IPTR ScrDecorClass__SDM_DRAW_SCREENBAR(Class *cl, Object *obj, struct sdpDrawScreenBar *msg)
353 struct scrdecor_data *data = INST_DATA(cl, obj);
354 struct RastPort *rp = msg->sdp_RPort;
355 UWORD *pens = DRI(data->dri)->dri_Pens;
356 LONG left, right;
357 BOOL beeping = FALSE;
359 #if 0
360 #if USE_NEWDISPLAYBEEP
361 beeping = (scr->Flags & BEEPING) && GetBitMapAttr(rp->BitMap, BMA_DEPTH) > 8;
362 #endif
363 #endif
365 SetDrMd(rp, JAM1);
367 SetAPen(rp, pens[beeping ? BARDETAILPEN : BARBLOCKPEN]);
368 RectFill(rp, 0, 0, data->scr->Width - 1, data->scr->BarHeight - 1);
370 SetAPen(rp, pens[beeping ? BARDETAILPEN : BARTRIMPEN]);
371 RectFill(rp, 0, data->scr->BarHeight, data->scr->Width - 1, data->scr->BarHeight);
373 findtitlearea(data->scr, &left, &right);
375 SetAPen(rp, pens[SHADOWPEN]);
376 RectFill(rp, right, 1, right, data->scr->BarHeight - 1);
378 return TRUE;
381 /**************************************************************************************************/
383 IPTR ScrDecorClass__SDM_DRAW_SCREENTITLE(Class *cl, Object *obj, struct sdpDrawScreenTitle *msg)
385 struct scrdecor_data *data = INST_DATA(cl, obj);
386 struct RastPort *rp = msg->sdp_RPort;
387 UWORD *pens = DRI(data->dri)->dri_Pens;
388 LONG right, left;
389 BOOL beeping = FALSE;
391 #if 0
392 #if USE_NEWDISPLAYBEEP
393 beeping = (scr->Flags & BEEPING) && GetBitMapAttr(rp->BitMap, BMA_DEPTH) > 8;
394 #endif
395 #endif
397 findtitlearea(data->scr, &left, &right);
399 SetDrMd(rp, JAM1);
401 SetAPen(rp, pens[beeping ? BARDETAILPEN : BARBLOCKPEN]);
402 RectFill(rp, left + 1, 0, right - 1, data->scr->BarHeight - 1);
404 SetAPen(rp, pens[beeping ? BARBLOCKPEN: BARDETAILPEN]);
405 SetBPen(rp, pens[beeping ? BARDETAILPEN : BARBLOCKPEN]);
407 Move(rp, data->scr->BarHBorder, data->scr->BarVBorder + rp->TxBaseline);
409 Text(rp, data->scr->Title, strlen(data->scr->Title));
411 return TRUE;
414 /**************************************************************************************************/
416 IPTR ScrDecorClass__SDM_LAYOUT_SCREENGADGETS(Class *cl, Object *obj, struct sdpLayoutScreenGadgets *msg)
418 struct Gadget *gadget = msg->sdp_Gadgets;
420 while(gadget)
422 switch(gadget->GadgetType & GTYP_SYSTYPEMASK)
424 case GTYP_SDEPTH:
425 gadget->LeftEdge = -gadget->Height + 1;
426 gadget->Width = gadget->Height;
427 gadget->Flags &= ~GFLG_RELWIDTH;
428 gadget->Flags |= GFLG_RELRIGHT;
429 break;
433 if (msg->sdp_Flags & SDF_LSG_MULTIPLE)
435 gadget = gadget->NextGadget;
437 else
439 gadget = NULL;
443 return TRUE;
446 /**************************************************************************************************/