revert between 56095 -> 55830 in arch
[AROS.git] / workbench / libs / popupmenu / window.c
blob1a31122643a276a55aa0818dc2074603b5a515b6
1 //
2 // Popup Menu Window funcs
3 // ©1996-2002 Henrik Isaksson
4 //
6 #include "pmpriv.h"
8 //
9 // Allocate memory and copy a RastPort structure
11 struct RastPort *PM_CpyRPort(struct RastPort *rp)
13 struct RastPort *rpc;
15 rpc=PM_Mem_Alloc(sizeof(struct RastPort));
16 if(rpc) {
17 CopyMem(rp, rpc, sizeof(struct RastPort));
20 return rpc;
24 // Copy the region beneath a window to the transparency buffer.
26 void PM_TransparencyBfr(struct PM_Window *bw)
28 int j, bpp;
29 ULONG transparent = FALSE;
31 #ifndef __AROS__
32 GetGUIAttrs(NULL, bw->p->DrawInfo, GUIA_MenuTransparency, &transparent, TAG_DONE);
33 #endif
35 if(CyberGfx && transparent) {
36 if(GetCyberMapAttr(bw->Wnd->WScreen->RastPort.BitMap, CYBRMATTR_ISCYBERGFX)) {
37 bpp = GetCyberMapAttr(bw->Wnd->WScreen->RastPort.BitMap, CYBRMATTR_BPPIX);
38 if(bpp<2)
39 return;
40 } else return;
42 // If we've gotten this far, the screen is CyberGfx and > 15 bpp
44 bw->bg.BgArray = PM_Mem_Alloc(3 * bw->Width * bw->Height);
45 if(bw->bg.BgArray) {
46 ReadPixelArray(bw->bg.BgArray, 0, 0,
47 bw->Width * 3, bw->RPort, 0, 0,
48 bw->Width, bw->Height, RECTFMT_RGB);
49 // Fast and simple way to blend the background to gray...
50 for(j = 0; j < bw->Width * bw->Height * 3; j++) {
51 bw->bg.BgArray[j] = (bw->bg.BgArray[j]>>2) + 150;
58 // Create an offscreen buffer for rendering animation and transition
59 // effects.
61 void PM_OffScreenBfr(struct PM_Window *bw)
63 if(PM_Prefs->pmp_Animation) {
64 bw->te.BMap=AllocBitMap(bw->Width, bw->Height, bw->Wnd->WScreen->RastPort.BitMap->Depth, BMF_MINPLANES, bw->Wnd->WScreen->RastPort.BitMap);
65 if(bw->te.BMap) {
66 bw->te.RPort=PM_CpyRPort(&bw->Wnd->WScreen->RastPort);
67 if(bw->te.RPort) {
68 bw->te.RPort->Layer = NULL; /* huuu! */
69 bw->te.RPort->BitMap = bw->te.BMap;
76 // Open a window
78 BOOL PM_OpenWindow(struct PM_Window *pw, int left, int top, int width, int height, struct Screen *scr)
80 pw->bg.BgArray = NULL;
81 pw->te.RPort = NULL;
82 pw->te.BMap = NULL;
83 pw->Wnd = OpenWindowTags(NULL,
84 WA_Borderless, TRUE,
85 WA_RMBTrap, TRUE,
86 WA_Left, left,
87 WA_Top, top,
88 WA_Width, width,
89 WA_Height, height,
90 //WA_ReportMouse, TRUE,
91 WA_CustomScreen, scr,
92 //WA_IDCMP, IDCMP_CLOSEWINDOW, // Kommer aldrig att inträffa - anv. för resize
93 WA_SmartRefresh, TRUE,
94 WA_BackFill, LAYERS_NOBACKFILL,
95 TAG_DONE);
97 if(pw->Wnd) {
98 pw->RPort = pw->Wnd->RPort;
100 /* Transparency/background image */
101 PM_TransparencyBfr(pw);
103 /* Transition effects */
104 PM_OffScreenBfr(pw);
106 return TRUE;
107 } else {
108 DisplayBeep(NULL);
109 return FALSE;
114 // Close a window
116 void PM_CloseWindow(struct PM_Window *bw)
118 if(bw->bg.BgArray) PM_Mem_Free(bw->bg.BgArray);
119 if(bw->te.RPort) PM_Mem_Free(bw->te.RPort);
120 if(bw->te.BMap) FreeBitMap(bw->te.BMap);
121 if(bw->Wnd) CloseWindow(bw->Wnd);
123 bw->bg.BgArray = NULL;
124 bw->te.RPort = NULL;
125 bw->te.BMap = NULL;
126 bw->Wnd = NULL;
130 // Resize a window
132 void PM_ResizeWindow(struct PM_Window *bw, int l, int t, int w, int h)
134 struct Message *msg;
136 if(l==bw->Wnd->LeftEdge && t==bw->Wnd->TopEdge && w==bw->Width && h==bw->Height)
137 return; // If no change
139 ModifyIDCMP(bw->Wnd, IDCMP_CLOSEWINDOW|IDCMP_NEWSIZE);
140 ChangeWindowBox(bw->Wnd, l, t, w, h);
141 WaitPort(bw->Wnd->UserPort);
142 while((msg=GetMsg(bw->Wnd->UserPort))) ReplyMsg(msg);
143 ModifyIDCMP(bw->Wnd, IDCMP_CLOSEWINDOW);
145 // bw->Width=bw->wnd->Width;
146 // bw->Height=bw->wnd->Height;
150 // Find out if we should close our submenu
154 // PM_InsideWindows(px, py, wnd)
156 // px, py - Screen coords
157 // wnd - PM_Window
160 BOOL PM_InsideWindows(int px, int py, struct PM_Window *wnd)
162 int x=px;
163 int y=py;
164 struct PM_Window *w;
166 w = wnd->Prev;
168 if(w) {
169 if(w->Selected) {
170 if(px > w->Wnd->LeftEdge + w->Selected->Left - 2 &&
171 px < w->Wnd->LeftEdge + w->Selected->Left + w->Selected->Width + 2 &&
172 py > w->Wnd->TopEdge + w->Selected->Top - 2 &&
173 py < w->Wnd->TopEdge + w->Selected->Top + w->Selected->Height + 2)
174 return FALSE;
178 while(w) {
179 if(x > w->Wnd->LeftEdge &&
180 y >= w->Wnd->TopEdge &&
181 x < w->Wnd->LeftEdge + w->Width &&
182 y < w->Wnd->TopEdge + w->Height) {
183 return TRUE;
185 w=w->Prev;
188 return FALSE;