Add a wishful comment
[AROS.git] / rom / intuition / scrdecorclass.c
blob83d23acf0af2adc23148873a120160a158eab88d
1 /*
2 Copyright © 1995-2013, The AROS Development Team. All rights reserved.
3 Copyright © 2001-2003, The MorphOS Development Team. All Rights Reserved.
4 $Id$
5 */
7 #define DEBUG 0
8 #include <aros/debug.h>
10 #include <dos/dos.h>
11 #include <dos/dosextens.h>
13 #include <intuition/intuition.h>
14 #include <intuition/intuitionbase.h>
15 #include <intuition/classes.h>
16 #include <intuition/classusr.h>
17 #include <intuition/scrdecorclass.h>
18 #include <intuition/cghooks.h>
19 #include <intuition/icclass.h>
20 #include <intuition/extensions.h>
22 #include <graphics/gfxbase.h>
23 #include <graphics/gfxmacros.h>
25 #include <utility/tagitem.h>
26 #include <utility/hooks.h>
28 #include <clib/macros.h>
30 #include <string.h>
32 #include <proto/exec.h>
33 #include <proto/intuition.h>
34 #include <proto/graphics.h>
35 #include <proto/utility.h>
37 #include <proto/alib.h>
39 #include "intuition_intern.h"
40 #include "gadgets.h"
42 /**************************************************************************************************/
44 #ifdef __AROS__
45 #define USE_AROS_DEFSIZE 1
46 #else
47 #define USE_AROS_DEFSIZE 0
48 #endif
50 #define DEFSIZE_WIDTH 14
51 #define DEFSIZE_HEIGHT 14
53 #define HSPACING 3
54 #define VSPACING 3
55 /* Ralph Schmidt
56 * heuristics for smaller arrows used in apps
57 * like filer
59 #define HSPACING_MIDDLE 2
60 #define VSPACING_MIDDLE 2
61 #define HSPACING_SMALL 1
62 #define VSPACING_SMALL 1
64 #define DRI(dri) ((struct DrawInfo *)(dri))
66 /**************************************************************************************************/
68 static void renderimageframe(struct RastPort *rp, ULONG which, ULONG state, UWORD *pens,
69 WORD left, WORD top, WORD width, WORD height,
70 struct IntuitionBase *IntuitionBase)
72 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
73 WORD right = left + width - 1;
74 WORD bottom = top + height - 1;
75 BOOL leftedgegodown = FALSE;
76 BOOL topedgegoright = FALSE;
78 if (left == 0) leftedgegodown = TRUE;
79 if (top == 0) topedgegoright = TRUE;
81 SetAPen(rp, pens[((state == IDS_SELECTED) || (state == IDS_INACTIVESELECTED)) ? SHADOWPEN : SHINEPEN]);
83 /* left edge */
84 RectFill(rp, left,
85 top,
86 left,
87 bottom - (leftedgegodown ? 0 : 1));
89 /* top edge */
90 RectFill(rp, left + 1,
91 top,
92 right - (topedgegoright ? 0 : 1),
93 top);
95 SetAPen(rp, pens[((state == IDS_SELECTED) || (state == IDS_INACTIVESELECTED)) ? SHINEPEN : SHADOWPEN]);
97 /* right edge */
98 RectFill(rp, right,
99 top + (topedgegoright ? 1 : 0),
100 right,
101 bottom);
103 /* bottom edge */
104 RectFill(rp, left + (leftedgegodown ? 1 : 0),
105 bottom,
106 right - 1,
107 bottom);
110 /**************************************************************************************************/
112 #if 0
113 static UWORD getbgpen(ULONG state, UWORD *pens)
115 UWORD bg;
117 switch (state)
119 case IDS_NORMAL:
120 case IDS_SELECTED:
121 bg = pens[FILLPEN];
122 break;
124 default:
125 bg = pens[BACKGROUNDPEN];
126 break;
129 return bg;
131 #endif
133 /**************************************************************************************************/
135 IPTR ScrDecorClass__OM_NEW(Class *cl, Object *obj, struct opSet *msg)
137 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
138 struct Library *UtilityBase = GetPrivIBase(IntuitionBase)->UtilityBase;
139 struct scrdecor_data *data;
141 D(bug("[SCRDECOR] ScrDecorClass__OM_NEW()\n"));
143 obj = (Object *)DoSuperMethodA(cl, obj, (Msg)msg);
144 if (obj)
146 data = INST_DATA(cl, obj);
148 data->userbuffersize = (ULONG) GetTagData(SDA_UserBuffer, 0, msg->ops_AttrList);
152 return (IPTR)obj;
155 /**************************************************************************************************/
157 IPTR ScrDecorClass__OM_GET(Class *cl, Object *obj, struct opGet *msg)
159 struct scrdecor_data *data = INST_DATA(cl, obj);
161 D(bug("[SCRDECOR] ScrDecorClass__OM_GET()\n"));
163 switch(msg->opg_AttrID)
165 case SDA_UserBuffer:
166 *msg->opg_Storage = (IPTR) data->userbuffersize;
167 break;
169 case SDA_TrueColorOnly:
170 *msg->opg_Storage = FALSE;
171 break;
173 default:
174 return DoSuperMethodA(cl, obj, (Msg)msg);
177 return 1;
181 /**************************************************************************************************/
183 IPTR ScrDecorClass__SDM_GETDEFSIZE_SYSIMAGE(Class *cl, Object *obj, struct sdpGetDefSizeSysImage *msg)
185 ULONG def_low_width = DEFSIZE_WIDTH, def_low_height = DEFSIZE_HEIGHT;
186 ULONG def_med_width = DEFSIZE_WIDTH, def_med_height = DEFSIZE_HEIGHT;
187 ULONG def_high_width = DEFSIZE_WIDTH, def_high_height = DEFSIZE_HEIGHT;
189 D(bug("[SCRDECOR] ScrDecorClass__SDM_GETDEFSIZE_SYSIMAGE()\n"));
191 switch(msg->sdp_Which)
193 case SDEPTHIMAGE:
194 #if USE_AROS_DEFSIZE
195 def_low_width = def_med_width = def_high_width = DEFSIZE_WIDTH;
196 def_low_height = def_med_height = def_high_height = DEFSIZE_HEIGHT;
197 #else
198 def_low_width = 17;
199 def_med_width = 23;
200 def_high_width = 23;
201 #endif
202 break;
204 default:
205 return FALSE;
208 switch(msg->sdp_SysiSize)
210 case SYSISIZE_LOWRES:
211 *msg->sdp_Width = def_low_width;
212 *msg->sdp_Height = def_low_height;
213 break;
215 case SYSISIZE_MEDRES:
216 *msg->sdp_Width = def_med_width;
217 *msg->sdp_Height = def_med_height;
218 break;
220 case SYSISIZE_HIRES:
221 default:
222 *msg->sdp_Width = def_high_width;
223 *msg->sdp_Height = def_high_height;
224 break;
227 return TRUE;
230 /**************************************************************************************************/
232 IPTR ScrDecorClass__SDM_DRAW_SYSIMAGE(Class *cl, Object *obj, struct sdpDrawSysImage *msg)
234 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
235 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
236 struct RastPort *rp = msg->sdp_RPort;
237 UWORD *pens = DRI(msg->sdp_Dri)->dri_Pens;
238 LONG state = msg->sdp_State;
239 LONG left = msg->sdp_X;
240 LONG top = msg->sdp_Y;
241 LONG width = msg->sdp_Width;
242 LONG height = msg->sdp_Height;
243 LONG right = left + width - 1;
244 LONG bottom = top + height - 1;
246 D(bug("[SCRDECOR] ScrDecorClass__SDM_DRAW_SYSIMAGE()\n"));
248 SetDrMd(rp, JAM1);
250 switch(msg->sdp_Which)
252 case SDEPTHIMAGE:
254 UWORD bg;
255 WORD h_spacing;
256 WORD v_spacing;
258 renderimageframe(rp, DEPTHIMAGE, state, pens,
259 left, top, width, height, IntuitionBase);
260 left++;
261 top++;
262 right--;
263 bottom--;
264 width -= 2;
265 height -= 2;
267 h_spacing = width / 6;
268 v_spacing = height / 6;
270 bg = pens[BACKGROUNDPEN];
272 /* Clear background into correct color */
273 SetAPen(rp, bg);
274 RectFill(rp, left, top, right, bottom);
276 /* Draw a image of two partly overlapped tiny windows,
279 left += h_spacing;
280 top += v_spacing;
282 width -= h_spacing * 2;
283 height -= v_spacing * 2;
285 right = left + width - 1;
286 bottom = top + height - 1;
288 /* Render top left window */
290 SetAPen(rp, pens[SHADOWPEN]);
291 drawrect(rp, left, top, right - (width / 3 ), bottom - (height / 3), IntuitionBase);
293 /* Render bottom right window */
294 SetAPen(rp, pens[SHADOWPEN]);
295 drawrect(rp, left + (width / 3), top + (height / 3), right, bottom, IntuitionBase);
297 /* Fill bottom right window (inside of the frame above) */
298 SetAPen(rp, pens[SHINEPEN]);
299 RectFill(rp, left + (width / 3) + 1, top + (height / 3) + 1,
300 right - 1, bottom - 1);
303 if (state == IDS_SELECTED)
305 /* Re-Render top left window */
307 SetAPen(rp, pens[SHADOWPEN]);
308 drawrect(rp, left, top, right - (width / 3 ), bottom - (height / 3), IntuitionBase);
310 break;
313 default:
314 return FALSE;
317 return TRUE;
320 /**************************************************************************************************/
322 static void findtitlearea(struct Screen *scr, LONG *left, LONG *right)
324 struct Gadget *g;
326 *left = 0;
327 *right = scr->Width - 1;
329 for (g = scr->FirstGadget; g; g = g->NextGadget)
331 if (!(g->Flags & GFLG_RELRIGHT))
333 if (g->LeftEdge + g->Width > *left)
334 *left = g->LeftEdge + g->Width;
336 else
338 if (g->LeftEdge + scr->Width - 1 - 1 < *right)
339 *right = g->LeftEdge + scr->Width - 1 - 1;
345 /**************************************************************************************************/
347 IPTR ScrDecorClass__SDM_DRAW_SCREENBAR(Class *cl, Object *obj, struct sdpDrawScreenBar *msg)
349 struct scrdecor_data *data = INST_DATA(cl, obj);
350 struct RastPort *rp = msg->sdp_RPort;
351 UWORD *pens = DRI(msg->sdp_Dri)->dri_Pens;
352 LONG left, right;
353 BOOL beeping = FALSE;
355 #if 0
356 #if USE_NEWDISPLAYBEEP
357 beeping = (msg->sdp_Screen->Flags & BEEPING) && GetBitMapAttr(rp->BitMap, BMA_DEPTH) > 8;
358 #endif
359 #endif
361 SetDrMd(rp, JAM1);
363 SetAPen(rp, pens[beeping ? BARDETAILPEN : BARBLOCKPEN]);
364 RectFill(rp, 0, 0, msg->sdp_Screen->Width - 1, msg->sdp_Screen->BarHeight - 1);
366 SetAPen(rp, pens[beeping ? BARDETAILPEN : BARTRIMPEN]);
367 RectFill(rp, 0, msg->sdp_Screen->BarHeight, msg->sdp_Screen->Width - 1, msg->sdp_Screen->BarHeight);
369 findtitlearea(msg->sdp_Screen, &left, &right);
371 SetAPen(rp, pens[SHADOWPEN]);
372 RectFill(rp, right, 1, right, msg->sdp_Screen->BarHeight - 1);
374 return TRUE;
378 /**************************************************************************************************/
380 IPTR ScrDecorClass__SDM_DRAW_SCREENBAR(Class *cl, Object *obj, struct sdpDrawScreenBar *msg)
382 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
383 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
384 struct RastPort *rp = msg->sdp_RPort;
385 UWORD *pens = DRI(msg->sdp_Dri)->dri_Pens;
386 LONG right, left;
387 BOOL beeping = FALSE;
389 D(bug("[SCRDECOR] ScrDecorClass__SDM_DRAW_SCREENBAR()\n"));
391 #if USE_NEWDISPLAYBEEP
392 beeping = msg->sdp_Screen->Flags & BEEPING;
393 #endif
395 findtitlearea(msg->sdp_Screen, &left, &right);
397 D(bug("[SCRDECOR] ScrDecorClass__SDM_DRAW_SCREENBAR: Title_Left = %d, Title_Right = %d\n", left, right));
399 D(bug("[SCRDECOR] ScrDecorClass__SDM_DRAW_SCREENBAR: RastPort @ %p, Screen @ %p\n", rp, msg->sdp_Screen));
400 D(bug("[SCRDECOR] ScrDecorClass__SDM_DRAW_SCREENBAR: Screen Dimensions %dx%d\n", msg->sdp_Screen->Width, msg->sdp_Screen->Height));
401 D(bug("[SCRDECOR] ScrDecorClass__SDM_DRAW_SCREENBAR: Bar Height %d\n", msg->sdp_Screen->BarHeight));
403 SetDrMd(rp, JAM1);
405 SetAPen(rp, pens[beeping ? BARDETAILPEN : BARBLOCKPEN]);
406 RectFill(rp, left + 1, 0, right - 1, msg->sdp_Screen->BarHeight - 1);
408 D(bug("[SCRDECOR] ScrDecorClass__SDM_DRAW_SCREENBAR: Filled Bar Area\n"));
410 SetAPen(rp, pens[beeping ? BARDETAILPEN : BARTRIMPEN]);
411 RectFill(rp, 0, msg->sdp_Screen->BarHeight, msg->sdp_Screen->Width - 1, msg->sdp_Screen->BarHeight);
413 D(bug("[SCRDECOR] ScrDecorClass__SDM_DRAW_SCREENBAR: Filled Bar Area\n"));
415 if (msg->sdp_Screen->Title)
417 SetAPen(rp, pens[beeping ? BARBLOCKPEN: BARDETAILPEN]);
418 SetBPen(rp, pens[beeping ? BARDETAILPEN : BARBLOCKPEN]);
420 Move(rp, msg->sdp_Screen->BarHBorder, msg->sdp_Screen->BarVBorder + rp->TxBaseline);
422 D(bug("[SCRDECOR] ScrDecorClass__SDM_DRAW_SCREENBAR: Title Text @ %p\n", msg->sdp_Screen->Title));
423 D(bug("[SCRDECOR] ScrDecorClass__SDM_DRAW_SCREENBAR: Title '%s'\n", msg->sdp_Screen->Title));
424 Text(rp, msg->sdp_Screen->Title, strlen(msg->sdp_Screen->Title));
426 D(bug("[SCRDECOR] ScrDecorClass__SDM_DRAW_SCREENBAR: Text Rendered\n"));
428 return TRUE;
431 /**************************************************************************************************/
433 IPTR ScrDecorClass__SDM_LAYOUT_SCREENGADGETS(Class *cl, Object *obj, struct sdpLayoutScreenGadgets *msg)
435 D(bug("[SCRDECOR] ScrDecorClass__SDM_LAYOUT_SCREENGADGETS()\n"));
438 * Nothing to do here any more.
439 * Proper default positioning is done by OpenScreen(). Use this method
440 * only if you actually want to change something.
443 return TRUE;
446 IPTR ScrDecorClass__SDM_INITSCREEN(Class *cl, Object *obj, struct sdpInitScreen *msg)
448 D(bug("[SCRDECOR] ScrDecorClass__SDM_INITSCREEN()\n"));
450 return TRUE;
453 IPTR ScrDecorClass__SDM_EXITSCREEN(Class *cl, Object *obj, struct sdpExitScreen *msg)
455 D(bug("[SCRDECOR] ScrDecorClass__SDM_EXITSCREEN()\n"));
457 return TRUE;
460 /**************************************************************************************************/