forgotten commit. disabled until egl is adapted.
[AROS-Contrib.git] / scalos / libraries / popupmenu / pmtopography.c
blobcf8961ed17e9c99d9b02a74e1c79f3c007ed0c9b
1 //
2 // pmtopography.h
3 //
4 // PopupMenu Library - Topographical Menu Map
5 //
6 // Copyright (C)2000 Henrik Isaksson <henrik@boing.nu>
7 // All Rights Reserved.
8 //
9 // $Date$
10 // $Revision$
13 #include "pmpriv.h"
14 #include "pmtopography.h"
16 #include <exec/lists.h>
17 #include <exec/memory.h>
18 #include <proto/exec.h>
19 #include <clib/alib_protos.h>
22 static BOOL PM_MapShadowPart(PMTRList *top, PMSRList *delta,
23 const PMSR *shrect, WORD l, WORD t, UWORD ss,
24 UWORD direction, UBYTE Type);
28 // PM_AddTopographicRegion - add a rectangular region of height h to the topographic map.
30 BOOL PM_AddTopographicRegion(PMTRList *lst, WORD l, WORD t, WORD r, WORD b, WORD h)
32 PMTR rect, *tmprect;
33 PMTR *worknode, *nextnode;
34 BOOL fail=FALSE;
36 rect.Left=l;
37 rect.Top=t;
38 rect.Right=r;
39 rect.Bottom=b;
40 rect.Height=h;
41 rect.n.Length=sizeof(PMTR);
43 d1(KPrintF("Adding topographic region: %ld %ld %ld %ld, height: %ld\n", l, t, r, b, h));
46 // Step 1: Remove all parts in l that would overlap rect.
48 worknode = (PMTR *)(lst->mlh_Head); /* First node */
49 while ((nextnode = (PMTR *)PM_NextNode(worknode)))
51 if (PM_RegionOverlap(worknode, &rect))
53 PM_UnlinkRegion(lst, worknode);
54 PM_SubTopographicRects(lst, worknode, &rect);
55 PM_FreeTopographicNode(worknode);
57 worknode = nextnode;
61 // Step 2: Add rect to l.
63 tmprect=PM_CopyTopographicNode(&rect);
64 if (tmprect)
66 PM_AddRegionToList(lst, tmprect);
68 else
69 fail = TRUE;
71 return (BOOL) !fail;
75 // PM_CopyTopographicNode - copy a PMTopographicRect, or allocate a new if A is NULL.
77 PMTR *PM_CopyTopographicNode(PMTR *A)
79 PMTR *newnode;
81 newnode=(PMTR *) AllocVec(sizeof(PMTR), MEMF_ANY);
82 if (newnode && A)
83 *newnode = *A;
85 return newnode;
89 // PM_SubTopographicRects - like PM_SubRects but preserves height
91 BOOL PM_SubTopographicRects(PMTRList *dest, PMTR *worknode, PMTR *rect)
93 PMTR tmprect, *rectptr;
94 BOOL fail = FALSE;
96 tmprect.Height = worknode->Height;
98 tmprect.Left = worknode->Left;
99 tmprect.Right = worknode->Right;
101 tmprect.n.Length = sizeof(tmprect);
103 if (rect->Top>worknode->Top && rect->Top<worknode->Bottom)
105 tmprect.Top = worknode->Top;
106 tmprect.Bottom = rect->Top;
108 rectptr = PM_CopyTopographicNode(&tmprect);
109 if (rectptr)
110 PM_AddToList((PMDList *)dest, (PMNode *)rectptr);
111 else
112 fail = TRUE;
115 if (rect->Bottom>worknode->Top && rect->Bottom<worknode->Bottom)
117 tmprect.Top = rect->Bottom;
118 tmprect.Bottom = worknode->Bottom;
120 rectptr = PM_CopyTopographicNode(&tmprect);
121 if (rectptr)
122 PM_AddToList((PMDList *)dest, (PMNode *)rectptr);
123 else
124 fail = TRUE;
127 tmprect.Top = MAX(rect->Top, worknode->Top);
128 tmprect.Bottom = MIN(rect->Bottom, worknode->Bottom);
130 if (rect->Left>worknode->Left && rect->Left<worknode->Right)
132 tmprect.Left = worknode->Left;
133 tmprect.Right = rect->Left;
135 rectptr = PM_CopyTopographicNode(&tmprect);
136 if (rectptr)
137 PM_AddToList((PMDList *)dest, (PMNode *)rectptr);
138 else
139 fail = TRUE;
142 if (rect->Right>worknode->Left && rect->Right<worknode->Right)
144 tmprect.Left = rect->Right;
145 tmprect.Right = worknode->Right;
147 rectptr = PM_CopyTopographicNode(&tmprect);
148 if (rectptr)
149 PM_AddShadowToList((PMDList *)dest, (PMNode *)rectptr);
150 else
151 fail = TRUE;
154 return (BOOL) !fail;
158 // PM_MapShadow
160 BOOL PM_MapShadow(PMTRList *top, PMSRList *delta,
161 WORD l, WORD t, WORD r, WORD b,
162 UWORD menulevel, UWORD direction)
164 PMSR shrect;
165 BOOL Success = TRUE;
166 UWORD ss;
168 shrect.Left = l;
169 shrect.Top = t;
170 shrect.Right = r;
171 shrect.Bottom = b;
174 // The five following calls will create shadows for a lightsource
175 // positioned somewhere near the top left corner of the screen.
177 // +------------+
178 // | |--+
179 // | |4 |
180 // | |--+
181 // | | |
182 // | |1 |
183 // | | |
184 // | | |
185 // +-+-+--------+--+
186 // |5| 2 |3 |
187 // +-+--------+--+
190 // Shadow size
191 ss = menulevel * 2 + 8;
193 d1(KPrintF("%s/%s/%ld: left=%ld top=%ld right=%ld bottom=%ld\n", __FILE__, __FUNC__, __LINE__, l, t, r, b));
195 if (direction & PMSHADOW_HORIZ)
197 shrect.Right = l + ss;
200 if (direction & PMSHADOW_VERT)
202 shrect.Bottom = t + ss;
205 if ((PMSHADOW_HORIZ | PMSHADOW_VERT) == direction)
207 // bottom right corner
208 // Shadow 3
209 d1(KPrintF("%s/%s/%ld: Shadow 3\n", __FILE__, __FUNC__, __LINE__));
210 Success = PM_MapShadowPart(top, delta, &shrect, l, t, ss, direction, SHADOWFLAG_BOTTOM | SHADOWFLAG_RIGHT);
212 else if (direction & PMSHADOW_HORIZ)
214 d1(KPrintF("%s/%s/%ld: PMSHADOW_HORIZ\n", __FILE__, __FUNC__, __LINE__));
215 // Shadow 4
216 shrect.Top = t;
217 shrect.Bottom = t + ss;
218 Success = PM_MapShadowPart(top, delta, &shrect, l, t, ss, direction, SHADOWFLAG_RIGHT | SHADOWFLAG_TOP);
220 if (Success)
222 // Shadow 1
223 shrect.Top = t + ss;
224 shrect.Bottom = b;
225 Success = PM_MapShadowPart(top, delta, &shrect, l, t, ss, direction, SHADOWFLAG_RIGHT);
228 else if (direction & PMSHADOW_VERT)
230 d1(KPrintF("%s/%s/%ld: PMSHADOW_VERT\n", __FILE__, __FUNC__, __LINE__));
231 // Shadow 5
232 shrect.Left = l;
233 shrect.Right = l + ss;
234 Success = PM_MapShadowPart(top, delta, &shrect, l, t, ss, direction, SHADOWFLAG_BOTTOM | SHADOWFLAG_LEFT);
236 if (Success)
238 // Shadow 2
239 shrect.Left = l + ss;
240 shrect.Right = r;
241 Success = PM_MapShadowPart(top, delta, &shrect, l, t, ss, direction, SHADOWFLAG_BOTTOM);
245 return Success;
249 static BOOL PM_MapShadowPart(PMTRList *top, PMSRList *delta,
250 const PMSR *shrect, WORD l, WORD t, UWORD ss,
251 UWORD direction, UBYTE Type)
253 PMTR *topnode, *nexttopnode;
254 BOOL Success = TRUE;
256 d1(KPrintF("%s/%s/%ld: Left=%ld Top=%ld Right=%ld Bottom=%ld\n", \
257 __FILE__, __FUNC__, __LINE__, shrect->Left, shrect->Top, shrect->Right, shrect->Bottom));
259 topnode = (PMTR *)(top->mlh_Head); /* First node */
260 while ((nexttopnode = (PMTR *)PM_NextNode(topnode)))
262 PMSR rect, *newnode;
263 UWORD dx, dy;
265 dx = dy = 0;
267 d1(KPrintF("Mapping shadow to region: %ld %ld %ld %ld, height: %ld\n", \
268 topnode->Left, topnode->Top, topnode->Right, topnode->Bottom, topnode->Height));
270 if (direction & PMSHADOW_HORIZ)
271 dx = topnode->Height * 2;
272 if (direction & PMSHADOW_VERT)
273 dy = topnode->Height * 2;
275 rect.pmsr_Type = Type;
277 rect.Left = MAX(shrect->Left, topnode->Left);
278 rect.Right = MIN(shrect->Right-dx, topnode->Right);
279 rect.Top = MAX(shrect->Top, topnode->Top);
280 rect.Bottom = MIN(shrect->Bottom-dy, topnode->Bottom);
281 rect.n.Length = sizeof(PMSR);
282 #if 0
283 if (direction & PMSHADOW_LEFT)
285 if (rect.Left < l + ss - (topnode->Height * 2))
286 rect.Left = l + ss - (topnode->Height * 2);
289 if (direction & PMSHADOW_TOP)
291 if (rect.Top < t+ss-(topnode->Height*2))
292 rect.Top = t+ss-(topnode->Height*2);
294 #endif
295 d1(KPrintF("%s/%s/%ld: Left=%ld Top=%ld RIght=%ld Bottom=%ld\n", \
296 __FILE__, __FUNC__, __LINE__, rect.Left, rect.Top, rect.Right, rect.Bottom));
297 if (rect.Right > rect.Left && rect.Bottom > rect.Top)
299 newnode = PM_CopyShadowNode(&rect);
300 if (newnode)
302 AddHead((struct List *)delta, (struct Node *)newnode);
304 else
306 Success = FALSE;
310 topnode = nexttopnode;
313 return Success;