4 // PopupMenu Library - Topographical Menu Map
6 // Copyright (C)2000 Henrik Isaksson <henrik@boing.nu>
7 // All Rights Reserved.
10 #include "pmtopography.h"
12 #include <exec/lists.h>
13 #include <exec/memory.h>
14 #include <proto/exec.h>
15 #include <clib/alib_protos.h>
18 // PM_AddTopographicRegion - add a rectangular region of height h to the topographic map.
20 BOOL
PM_AddTopographicRegion(PMTRList
*lst
, WORD l
, WORD t
, WORD r
, WORD b
, WORD h
)
23 PMTR
*worknode
, *nextnode
;
31 rect
.n
.Length
=sizeof(PMTR
);
33 //kprintf("Adding topographic region: %ld %ld %ld %ld, height: %ld\n", l, t, r, b, h);
36 // Step 1: Remove all parts in l that would overlap rect.
38 worknode
= (PMTR
*)(lst
->mlh_Head
); /* First node */
39 while((nextnode
= (PMTR
*)PM_NextNode(worknode
))) {
40 if(PM_RegionOverlap(worknode
, &rect
)) {
41 PM_UnlinkRegion(lst
, worknode
);
42 PM_SubTopographicRects(lst
, worknode
, &rect
);
43 PM_FreeTopographicNode(worknode
);
49 // Step 2: Add rect to l.
51 tmprect
=PM_CopyTopographicNode(&rect
);
53 PM_AddRegionToList(lst
, tmprect
);
60 // PM_CopyTopographicNode - copy a PMTopographicRect, or allocate a new if A is NULL.
62 PMTR
*PM_CopyTopographicNode(PMTR
*A
)
66 newnode
=(PMTR
*)AllocVec(sizeof(PMTR
), MEMF_ANY
);
69 CopyMem(A
, newnode
, sizeof(PMTR
));
77 // PM_SubTopographicRects - like PM_SubRects but preserves height
79 BOOL
PM_SubTopographicRects(PMTRList
*dest
, PMTR
*worknode
, PMTR
*rect
)
81 PMTR tmprect
, *rectptr
;
84 tmprect
.Height
=worknode
->Height
;
86 tmprect
.Left
=worknode
->Left
;
87 tmprect
.Right
=worknode
->Right
;
90 tmprect
.n
.Length
=sizeof(tmprect
);
92 if(rect
->Top
>worknode
->Top
&& rect
->Top
<worknode
->Bottom
) {
93 tmprect
.Top
=worknode
->Top
;
94 tmprect
.Bottom
=rect
->Top
;
96 rectptr
=PM_CopyTopographicNode(&tmprect
);
97 if(rectptr
) PM_AddToList((PMDList
*)dest
, (PMNode
*)rectptr
);
101 if(rect
->Bottom
>worknode
->Top
&& rect
->Bottom
<worknode
->Bottom
) {
102 tmprect
.Top
=rect
->Bottom
;
103 tmprect
.Bottom
=worknode
->Bottom
;
105 rectptr
=PM_CopyTopographicNode(&tmprect
);
106 if(rectptr
) PM_AddToList((PMDList
*)dest
, (PMNode
*)rectptr
);
110 tmprect
.Top
=MAX(rect
->Top
, worknode
->Top
);
111 tmprect
.Bottom
=MIN(rect
->Bottom
, worknode
->Bottom
);
113 if(rect
->Left
>worknode
->Left
&& rect
->Left
<worknode
->Right
) {
114 tmprect
.Left
=worknode
->Left
;
115 tmprect
.Right
=rect
->Left
;
117 rectptr
=PM_CopyTopographicNode(&tmprect
);
118 if(rectptr
) PM_AddToList((PMDList
*)dest
, (PMNode
*)rectptr
);
122 if(rect
->Right
>worknode
->Left
&& rect
->Right
<worknode
->Right
) {
123 tmprect
.Left
=rect
->Right
;
124 tmprect
.Right
=worknode
->Right
;
126 rectptr
=PM_CopyTopographicNode(&tmprect
);
127 if(rectptr
) PM_AddShadowToList((PMDList
*)dest
, (PMNode
*)rectptr
);
131 return (!(BOOL
)fail
);
137 BOOL
PM_MapShadow(PMTRList
*top
, PMSRList
*delta
,
138 WORD l
, WORD t
, WORD r
, WORD b
,
139 UWORD menulevel
, UWORD direction
)
141 PMTR
*topnode
, *nexttopnode
;
142 PMSR rect
, shrect
, *newnode
;
153 if(direction
&PMSHADOW_HORIZ
) {
157 if(direction
&PMSHADOW_VERT
) {
161 topnode
= (PMTR
*)(top
->mlh_Head
); /* First node */
162 while((nexttopnode
= (PMTR
*)PM_NextNode(topnode
))) {
166 //kprintf("Mapping shadow to region: %ld %ld %ld %ld, height: %ld\n", topnode->Left, topnode->Top, topnode->Right, topnode->Bottom, topnode->Height);
169 if(direction
&PMSHADOW_HORIZ
) dx
=topnode
->Height
*2;
170 if(direction
&PMSHADOW_VERT
) dy
=topnode
->Height
*2;
172 rect
.Left
=MAX(shrect
.Left
, topnode
->Left
);
173 rect
.Right
=MIN(shrect
.Right
-dx
, topnode
->Right
);
174 rect
.Top
=MAX(shrect
.Top
, topnode
->Top
);
175 rect
.Bottom
=MIN(shrect
.Bottom
-dy
, topnode
->Bottom
);
176 rect
.n
.Length
=sizeof(PMSR
);
178 if(direction
&PMSHADOW_LEFT
) {
179 if(rect
.Left
<l
+ss
-(topnode
->Height
*2))
180 rect
.Left
=l
+ss
-(topnode
->Height
*2);
183 if(direction
&PMSHADOW_TOP
) {
184 if(rect
.Top
<t
+ss
-(topnode
->Height
*2))
185 rect
.Top
=t
+ss
-(topnode
->Height
*2);
188 if(rect
.Right
>rect
.Left
&& rect
.Bottom
>rect
.Top
) {
189 newnode
=PM_CopyShadowNode(&rect
);
191 AddHead((struct List
*)delta
, (struct Node
*)newnode
);
198 return (!(BOOL
)fail
);