2 Copyright 1999, David Le Corfec.
3 Copyright 2002-2006, The AROS Development Team.
8 #include <exec/types.h>
9 #include <exec/memory.h>
13 #include <intuition/imageclass.h>
14 #include <intuition/icclass.h>
15 #include <intuition/gadgetclass.h>
17 #include <intuition/extensions.h>
19 #include <clib/alib_protos.h>
20 #include <graphics/gfxmacros.h>
21 #include <proto/exec.h>
22 #include <proto/intuition.h>
23 #include <proto/utility.h>
24 #include <proto/graphics.h>
25 #include <proto/commodities.h>
26 #include <proto/layers.h>
27 #include <proto/gadtools.h>
28 #include <proto/muimaster.h>
30 #define MUI_OBSOLETE /* for the obsolete menu stuff */
34 #include "classes/window.h"
35 #include "classes/area.h"
37 #include "datatypescache.h"
39 #include "dragndrop.h"
41 #include "muimaster_intern.h"
46 extern struct Library
*MUIMasterBase
;
48 static const int __version
= 1;
49 static const int __revision
= 1;
51 #define IM(x) ((struct Image*)(x))
52 #define G(x) ((struct Gadget*)(x))
53 #define GADGETID(x) (((struct Gadget*)(x))->GadgetID)
55 /* this is for the cycle list */
62 /* For the gadget ids */
69 struct MUI_ImageSpec_intern
;
73 struct MUI_RenderInfo wd_RenderInfo
;
74 struct MUI_MinMax wd_MinMax
;
75 struct IBox wd_AltDim
; /* zoomed dimensions */
76 BOOL wd_ZoomGadget
; /* enable/disable zoomgadget (altdim stuff) */
77 APTR wd_MemoryPool
; /* for nodes and stuff to deallocate at OM_DISPOSE */
78 struct MinList wd_CycleChain
; /* objects activated with tab */
79 struct MinList wd_EHList
; /* event handlers */
80 struct MinList wd_CCList
; /* control chars */
81 struct MinList wd_IDList
; /* gadget ids */
82 ULONG wd_Events
; /* events received */
83 ULONG wd_CrtFlags
; /* window creation flags, see below */
84 Object
*wd_ActiveObject
; /* the active object */
85 Object
*wd_OldActive
; /* active object before window was closed */
86 APTR wd_DefaultObject
;
89 STRPTR wd_ScreenTitle
;
90 LONG wd_Height
; /* Current dimensions */
94 LONG wd_ReqHeight
; /* given by programmer */
96 APTR wd_RootObject
; /* unique child */
97 ULONG wd_Flags
; /* various status flags */
98 struct MUI_ImageSpec_intern
*wd_Background
;
99 ULONG wd_DisabledKeys
;
100 BOOL wd_NoMenus
; /* MUIA_Window_NoMenus */
102 Object
*wd_DragObject
; /* the object which is being dragged */
103 struct Window
*wd_DropWindow
; /* the destination window, for faster access */
104 Object
*wd_DropObject
; /* the destination object */
105 struct DragNDrop
*wd_dnd
;
106 struct MUI_DragImage
*wd_DragImage
;
108 Object
*wd_Menustrip
; /* The menustrip object which is actually is used (either apps or windows or NULL) */
109 Object
* wd_ChildMenustrip
; /* If window has an own Menustrip */
110 struct Menu
*wd_Menu
; /* the intuition menustrip */
114 Object
*wd_DownButton
;
116 Object
*wd_HorizProp
;
117 Object
*wd_LeftButton
;
118 Object
*wd_RightButton
;
119 Object
*wd_RefWindow
;
121 Object
*wd_MUIGadget
;
123 Object
*wd_HelpObject
;
127 struct Screen
*wd_UserScreen
;
128 STRPTR wd_UserPublicScreen
;
129 LONG wd_XStore
; /*store MUIV_Window_LeftEdge_Centered Tags etc
130 because wd_X is overwritten by a value in CalcDimension
131 Popup windows work ok on AmiGG when main window is move
136 #ifndef WFLG_SIZEGADGET
138 #define WFLG_CLOSEGADGET (1<<0) /* has close gadget */
139 #define WFLG_SIZEGADGET (1<<1) /* has size gadget */
140 #define WFLG_BACKDROP (1<<2) /* is backdrop window */
141 #define WFLG_BORDERLESS (1<<3) /* has no borders */
142 #define WFLG_DEPTHGADGET (1<<4) /* has depth gadget */
143 #define WFLG_DRAGBAR (1<<5) /* is draggable */
144 #define WFLG_SIZEBRIGHT (1<<6) /* size gadget is in right border */
149 #define MUIWF_OPENED (1<<0) /* window currently opened */
150 #define MUIWF_HIDDEN (1<<1) /* window currently iconified */
151 #define MUIWF_ACTIVE (1<<2) /* window currently active */
152 #define MUIWF_RESIZING (1<<4) /* window currently resizing, for simple refresh */
153 #define MUIWF_DONTACTIVATE (1<<7) /* do not activate the window when opening */
154 #define MUIWF_USERIGHTSCROLLER (1<<8) /* window should have a right scroller */
155 #define MUIWF_USEBOTTOMSCROLLER (1<<9) /* window should have a bottom scroller */
156 #define MUIWF_ERASEAREA (1<<10) /* Erase area after a window resize */
157 #define MUIWF_ISAPPWINDOW (1<<11) /* Is an app window (user can drop icons on it) */
158 #define MUIWF_ISSUBWINDOW (1<<12) /* Dont get automatically disposed with app */
159 #define MUIWF_BUBBLEMODE (1<<13) /* Quick bubble mode. Bubbles appear quick when moving */
160 #define MUIWF_OPENONUNHIDE (1<<14) /* Open the window when unhiding */
161 #define MUIWF_SCREENLOCKED (1<<15) /* A pub screen was locked in SetupRenderInfo. Unlock it in CleanupRenderInfo! */
162 #define MUIWF_OBJECTGOACTIVESENT (1<<16) /* A MUIM_GoActive msg was sent to window's active object */
163 #define MUIWF_TOOLBOX (1<<17) /* Window should be opened as ToolBox */
165 #define BUBBLEHELP_TICKER_FIRST 10
166 #define BUBBLEHELP_TICKER_LATER 3
170 struct MUI_NotifyData mnd
;
171 struct MUI_WindowData mwd
;
174 #define muiWindowData(obj) (&(((struct __dummyXFC3__ *)(obj))->mwd))
176 static ULONG
DoHalfshineGun(ULONG a
, ULONG b
)
178 ULONG val
= ((((a
)>>24) + 3 * ((b
)>>24)) / 4);
179 val
= val
+ (val
<<8) + (val
<<16) + (val
<<24);
183 static ULONG
DoHalfshadowGun(ULONG a
, ULONG b
)
185 ULONG val
= ((((a
)>>24) + 5 * ((b
)>>24)) / 6);
186 val
= val
+ (val
<<8) + (val
<<16) + (val
<<24);
190 static Object
*CreateSysimage(struct DrawInfo
*dri
, ULONG which
)
192 return NewObject(NULL
, "sysiclass",
193 SYSIA_DrawInfo
, (IPTR
)dri
,
198 static void EnqueueByPriAndAddress(struct List
*list
, struct Node
*node
)
200 struct Node
*scannode
;
202 /* Sort by priority and by node address, so that a
203 "remove - modify - enqueue" sequence will re-add
204 the node at the same place in the list it was
207 ForeachNode(list
, scannode
)
209 if (((struct Node
*)node
)->ln_Pri
> scannode
->ln_Pri
) break;
210 if (((struct Node
*)node
)->ln_Pri
== scannode
->ln_Pri
)
212 if ((IPTR
)node
> (IPTR
)scannode
) break;
216 Insert(list
, (struct Node
*)node
, scannode
->ln_Pred
);
219 static BOOL
InitCustomFrames(Object
*obj
, struct MUI_RenderInfo
*mri
)
223 for (i
= 0; i
< 16; i
++)
225 mri
->mri_FrameImage
[i
] = NULL
;
228 mri
->mri_FrameImage
[0] = load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->customframe_config_1
, mri
->mri_Screen
);
229 mri
->mri_FrameImage
[1] = load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->customframe_config_2
, mri
->mri_Screen
);
230 mri
->mri_FrameImage
[2] = load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->customframe_config_3
, mri
->mri_Screen
);
231 mri
->mri_FrameImage
[3] = load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->customframe_config_4
, mri
->mri_Screen
);
232 mri
->mri_FrameImage
[4] = load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->customframe_config_5
, mri
->mri_Screen
);
233 mri
->mri_FrameImage
[5] = load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->customframe_config_6
, mri
->mri_Screen
);
234 mri
->mri_FrameImage
[6] = load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->customframe_config_7
, mri
->mri_Screen
);
235 mri
->mri_FrameImage
[7] = load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->customframe_config_8
, mri
->mri_Screen
);
236 mri
->mri_FrameImage
[8] = load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->customframe_config_9
, mri
->mri_Screen
);
237 mri
->mri_FrameImage
[9] = load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->customframe_config_10
, mri
->mri_Screen
);
238 mri
->mri_FrameImage
[10] = load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->customframe_config_11
, mri
->mri_Screen
);
239 mri
->mri_FrameImage
[11] = load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->customframe_config_12
, mri
->mri_Screen
);
240 mri
->mri_FrameImage
[12] = load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->customframe_config_13
, mri
->mri_Screen
);
241 mri
->mri_FrameImage
[13] = load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->customframe_config_14
, mri
->mri_Screen
);
242 mri
->mri_FrameImage
[14] = load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->customframe_config_15
, mri
->mri_Screen
);
243 mri
->mri_FrameImage
[15] = load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->customframe_config_16
, mri
->mri_Screen
);
248 static void DisposeCustomFrames(struct MUI_RenderInfo
*mri
)
252 for (i
= 0; i
< 16; i
++)
254 dispose_custom_frame(mri
->mri_FrameImage
[i
]);
256 mri
->mri_FrameImage
[i
] = NULL
;
260 static BOOL
SetupRenderInfo(Object
*obj
, struct MUI_WindowData
*data
, struct MUI_RenderInfo
*mri
)
262 ULONG rgbtable
[3 * 3];
267 /* TODO: Move this whole screen locking/opening stuff into the application class
268 * by creating methods for this purpose */
270 /* If no user screen has been specified try to open the application specifc screen */
271 if (!data
->wd_UserScreen
)
273 ULONG screenmodeid
= muiGlobalInfo(obj
)->mgi_Prefs
->screenmodeid
;
275 if (screenmodeid
!= ~0)
277 if (!muiGlobalInfo(obj
)->mgi_CustomScreen
)
279 muiGlobalInfo(obj
)->mgi_CustomScreen
= OpenScreenTags(NULL
,
280 SA_DisplayID
, screenmodeid
,
282 SA_FullPalette
, TRUE
,
283 SA_LikeWorkbench
,TRUE
,
285 /* It's fine if this fails as there is a back fall case below */
288 data
->wd_UserScreen
= muiGlobalInfo(obj
)->mgi_CustomScreen
;
292 if (data
->wd_UserScreen
)
294 mri
->mri_Screen
= data
->wd_UserScreen
;
298 if (!(mri
->mri_Screen
= LockPubScreen(data
->wd_UserPublicScreen
)))
300 if (!(mri
->mri_Screen
= LockPubScreen(NULL
)))
306 data
->wd_Flags
|= MUIWF_SCREENLOCKED
;
309 if (!(mri
->mri_DrawInfo
= GetScreenDrawInfo(mri
->mri_Screen
)))
311 if (data
->wd_Flags
& MUIWF_SCREENLOCKED
)
313 UnlockPubScreen(NULL
,mri
->mri_Screen
);
314 data
->wd_Flags
&= ~MUIWF_SCREENLOCKED
;
319 if (!InitCustomFrames(obj
, mri
))
321 if (data
->wd_Flags
& MUIWF_SCREENLOCKED
)
323 UnlockPubScreen(NULL
,mri
->mri_Screen
);
324 data
->wd_Flags
&= ~MUIWF_SCREENLOCKED
;
329 mri
->mri_Colormap
= mri
->mri_Screen
->ViewPort
.ColorMap
;
330 mri
->mri_ScreenWidth
= mri
->mri_Screen
->Width
;
331 mri
->mri_ScreenHeight
= mri
->mri_Screen
->Height
;
333 if (mri
->mri_ScreenWidth
/ mri
->mri_ScreenHeight
< 2)
335 mri
->mri_Flags
|= MUIMRI_THINFRAMES
;
338 if (GetBitMapAttr(mri
->mri_Screen
->RastPort
.BitMap
, BMA_DEPTH
) >= 15)
340 mri
->mri_Flags
|= MUIMRI_TRUECOLOR
;
343 mri
->mri_PensStorage
[MPEN_SHINE
] = mri
->mri_DrawInfo
->dri_Pens
[SHINEPEN
];
344 mri
->mri_PensStorage
[MPEN_BACKGROUND
] = mri
->mri_DrawInfo
->dri_Pens
[BACKGROUNDPEN
];
345 mri
->mri_PensStorage
[MPEN_SHADOW
] = mri
->mri_DrawInfo
->dri_Pens
[SHADOWPEN
];
346 mri
->mri_PensStorage
[MPEN_TEXT
] = mri
->mri_DrawInfo
->dri_Pens
[TEXTPEN
];
347 mri
->mri_PensStorage
[MPEN_FILL
] = mri
->mri_DrawInfo
->dri_Pens
[FILLPEN
];
349 GetRGB32(mri
->mri_Colormap
, mri
->mri_DrawInfo
->dri_Pens
[SHINEPEN
], 1, rgbtable
);
350 GetRGB32(mri
->mri_Colormap
, mri
->mri_DrawInfo
->dri_Pens
[BACKGROUNDPEN
], 1, rgbtable
+3);
351 GetRGB32(mri
->mri_Colormap
, mri
->mri_DrawInfo
->dri_Pens
[SHADOWPEN
], 1, rgbtable
+6);
353 mri
->mri_PensStorage
[MPEN_HALFSHINE
] = ObtainBestPenA
356 DoHalfshineGun(rgbtable
[0], rgbtable
[3]),
357 DoHalfshineGun(rgbtable
[1], rgbtable
[4]),
358 DoHalfshineGun(rgbtable
[2], rgbtable
[5]), NULL
361 mri
->mri_PensStorage
[MPEN_HALFSHADOW
] = ObtainBestPenA
364 DoHalfshadowGun(rgbtable
[6], rgbtable
[3]),
365 DoHalfshadowGun(rgbtable
[7], rgbtable
[4]),
366 DoHalfshadowGun(rgbtable
[8], rgbtable
[5]), NULL
369 /* I'm really not sure that MUI does this for MPEN_MARK, but it seems mostly acceptable -dlc */
370 mri
->mri_PensStorage
[MPEN_MARK
] = ObtainBestPenA
372 mri
->mri_Colormap
, 0xf4f4f4f4, 0xb5b5b5b5, 0x8b8b8b8b, NULL
375 mri
->mri_Pens
= mri
->mri_PensStorage
;
377 for (i
= 0; i
< -MUIV_Font_NegCount
; i
++)
379 mri
->mri_Fonts
[i
] = NULL
;
382 if (data
->wd_Flags
& MUIWF_USEBOTTOMSCROLLER
)
384 mri
->mri_LeftImage
= CreateSysimage(mri
->mri_DrawInfo
, LEFTIMAGE
);
385 mri
->mri_RightImage
= CreateSysimage(mri
->mri_DrawInfo
, RIGHTIMAGE
);
389 mri
->mri_LeftImage
= mri
->mri_RightImage
= NULL
;
392 if (data
->wd_Flags
& MUIWF_USERIGHTSCROLLER
)
394 mri
->mri_UpImage
= CreateSysimage(mri
->mri_DrawInfo
, UPIMAGE
);
395 mri
->mri_DownImage
= CreateSysimage(mri
->mri_DrawInfo
, DOWNIMAGE
);
399 mri
->mri_UpImage
= mri
->mri_DownImage
= NULL
;
402 if ((data
->wd_Flags
& MUIWF_USEBOTTOMSCROLLER
) ||
403 (data
->wd_Flags
& MUIWF_USERIGHTSCROLLER
))
404 mri
->mri_SizeImage
= CreateSysimage(mri
->mri_DrawInfo
, SIZEIMAGE
);
406 mri
->mri_SizeImage
= NULL
;
408 if (data
->wd_CrtFlags
& WFLG_BORDERLESS
)
410 /* Infact borderless windows could also have borders (if they have a window title e.g. but
411 since they look ugly anywhy we ignore it for now */
412 mri
->mri_BorderLeft
= 0;
413 mri
->mri_BorderRight
= 0;
414 mri
->mri_BorderTop
= 0;
415 mri
->mri_BorderBottom
= 0;
419 mri
->mri_BorderLeft
= mri
->mri_Screen
->WBorLeft
;
420 mri
->mri_BorderTop
= mri
->mri_Screen
->WBorTop
+ mri
->mri_Screen
->Font
->ta_YSize
+ 1;
424 SYSIA_DrawInfo
, (IPTR
)mri
->mri_DrawInfo
,
425 SYSIA_Which
, SIZEIMAGE
,
430 GetAttr(IA_Height
,temp_obj
,&val
);
431 DisposeObject(temp_obj
);
432 mri
->mri_BorderBottom
= val
;
435 mri
->mri_BorderBottom
= mri
->mri_Screen
->WBorBottom
;
441 static void CleanupRenderInfo(Object
*obj
, struct MUI_WindowData
*data
, struct MUI_RenderInfo
*mri
)
445 DisposeCustomFrames(mri
);
447 if (mri
->mri_LeftImage
) {DisposeObject(mri
->mri_LeftImage
);mri
->mri_LeftImage
=NULL
;};
448 if (mri
->mri_RightImage
){DisposeObject(mri
->mri_RightImage
);mri
->mri_RightImage
=NULL
;};
449 if (mri
->mri_UpImage
) {DisposeObject(mri
->mri_UpImage
);mri
->mri_UpImage
=NULL
;};
450 if (mri
->mri_DownImage
) {DisposeObject(mri
->mri_DownImage
);mri
->mri_DownImage
=NULL
;};
451 if (mri
->mri_SizeImage
) {DisposeObject(mri
->mri_SizeImage
);mri
->mri_SizeImage
=NULL
;};
453 /* bug("CleanupRenderInfo\n"); */
454 for (i
= 0; i
< -MUIV_Font_NegCount
; i
++)
456 if (mri
->mri_Fonts
[i
])
458 /* bug("CleanupRenderInfo: closing font %p (%s/%d)\n", */
459 /* mri->mri_Fonts[i], mri->mri_Fonts[i]->tf_Message.mn_Node.ln_Name, */
460 /* mri->mri_Fonts[i]->tf_YSize); */
461 CloseFont(mri
->mri_Fonts
[i
]);
462 mri
->mri_Fonts
[i
] = NULL
;
465 ReleasePen(mri
->mri_Colormap
, mri
->mri_PensStorage
[MPEN_MARK
]);
466 ReleasePen(mri
->mri_Colormap
, mri
->mri_PensStorage
[MPEN_HALFSHADOW
]);
467 ReleasePen(mri
->mri_Colormap
, mri
->mri_PensStorage
[MPEN_HALFSHINE
]);
468 FreeScreenDrawInfo(mri
->mri_Screen
, mri
->mri_DrawInfo
);
469 mri
->mri_DrawInfo
= NULL
;
471 /* If a custom screen has been opened by zune, close it as soon as
472 * zero windows are opened. See above for comments about refactorization. */
473 if (muiGlobalInfo(obj
)->mgi_CustomScreen
)
475 BOOL screenclose
= TRUE
;
476 Object
*_app
= _app(obj
);
479 struct List
*store
= NULL
;
480 get(_app
, MUIA_Application_WindowList
, &store
);
483 if (!IsListEmpty(store
)) screenclose
= FALSE
;
488 /* If the window's user screen really was the custom screen, clear the reference */
489 if (data
->wd_UserScreen
== muiGlobalInfo(obj
)->mgi_CustomScreen
)
490 data
->wd_UserScreen
= NULL
;
492 CloseScreen(muiGlobalInfo(obj
)->mgi_CustomScreen
);
493 muiGlobalInfo(obj
)->mgi_CustomScreen
= NULL
;
498 if (data
->wd_Flags
& MUIWF_SCREENLOCKED
)
500 UnlockPubScreen(NULL
, mri
->mri_Screen
);
501 data
->wd_Flags
&= ~MUIWF_SCREENLOCKED
;
503 mri
->mri_Screen
= NULL
;
506 static void ShowRenderInfo(struct MUI_RenderInfo
*mri
)
508 if (mri
->mri_BufferBM
)
510 mri
->mri_RastPort
= &mri
->mri_BufferRP
;
514 mri
->mri_RastPort
= mri
->mri_Window
->RPort
;
518 static void HideRenderInfo(struct MUI_RenderInfo
*mri
)
520 mri
->mri_RastPort
= NULL
;
523 static ULONG
GetDefaultEvents (void)
525 return IDCMP_NEWSIZE
| IDCMP_REFRESHWINDOW
526 | IDCMP_MOUSEBUTTONS
| IDCMP_MOUSEMOVE
| IDCMP_MENUPICK
527 | IDCMP_CLOSEWINDOW
| IDCMP_RAWKEY
| IDCMP_INTUITICKS
528 | IDCMP_ACTIVEWINDOW
| IDCMP_INACTIVEWINDOW
| IDCMP_GADGETUP
;
531 static void ChangeEvents (struct MUI_WindowData
*data
, ULONG new_events
)
534 struct MUI_EventHandlerNode
*ehn
;
535 ULONG old_events
= data
->wd_Events
;
537 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
539 ehn
= (struct MUI_EventHandlerNode
*)mn
;
540 new_events
|= ehn
->ehn_Events
;
543 /* sba: kill the IDCMP_VANILLAKEY flag. MUI doesn't do this but programs
544 ** which use this will behave different if they request for this flag
547 new_events
&= ~IDCMP_VANILLAKEY
;
549 data
->wd_Events
= new_events
;
550 if ((old_events
!= new_events
) && (data
->wd_Flags
& MUIWF_OPENED
))
552 ModifyIDCMP(data
->wd_RenderInfo
.mri_Window
, new_events
);
556 static void CalcWindowPosition(Object
*obj
, struct MUI_WindowData
*data
);
557 static void CreateWindowScrollbars(Object
*obj
, struct MUI_WindowData
*data
);
558 static void CalcAltDimensions(Object
*obj
, struct MUI_WindowData
*data
);
559 static void UndisplayWindow(Object
*obj
, struct MUI_WindowData
*data
);
560 static struct ObjNode
*FindObjNode(struct MinList
*list
, Object
*obj
);
562 static BOOL
DisplayWindow(Object
*obj
, struct MUI_WindowData
*data
)
565 ULONG flags
= data
->wd_CrtFlags
;
567 ULONG backfill
, buttons
;
569 struct Menu
*menu
= NULL
;
570 struct NewMenu
*newmenu
= NULL
;
575 if (!(data
->wd_Flags
& MUIWF_DONTACTIVATE
))
577 flags
|= WFLG_ACTIVATE
;
580 /* Toolboxes are handled differently on AmigaOS */
582 if (data
->wd_Flags
& MUIWF_TOOLBOX
)
583 flags
|= WFLG_TOOLBOX
;
588 data
->wd_MinMax
.MinHeight
== data
->wd_MinMax
.MaxHeight
589 && data
->wd_MinMax
.MinWidth
== data
->wd_MinMax
.MaxWidth
591 flags
&= ~WFLG_SIZEGADGET
;
593 if (!(flags
& WFLG_SIZEBRIGHT
))
594 flags
|= WFLG_SIZEBBOTTOM
;
596 CalcWindowPosition(obj
, data
);
598 if ((visinfo
= GetVisualInfoA(data
->wd_RenderInfo
.mri_Screen
,NULL
)))
600 if (data
->wd_Menustrip
)
602 get(data
->wd_Menustrip
,MUIA_Menuitem_NewMenu
,&newmenu
);
605 if ((menu
= CreateMenusA(newmenu
,NULL
)))
607 struct TagItem tags
[] =
609 { GTMN_NewLookMenus
, TRUE
},
610 { TAG_DONE
, (IPTR
)NULL
}
612 LayoutMenusA(menu
, visinfo
, tags
);
616 FreeVisualInfo(visinfo
);
619 CreateWindowScrollbars(obj
, data
);
620 CalcAltDimensions(obj
, data
);
621 altdims
= data
->wd_AltDim
;
622 /* hack to account for border size, as we only know the innersize and must give
625 altdims
.Width
+= data
->wd_RenderInfo
.mri_Screen
->WBorLeft
+ data
->wd_RenderInfo
.mri_Screen
->WBorRight
;
626 altdims
.Height
+= data
->wd_RenderInfo
.mri_Screen
->WBorTop
+ data
->wd_RenderInfo
.mri_Screen
->WBorBottom
+
627 data
->wd_RenderInfo
.mri_DrawInfo
->dri_Font
->tf_YSize
+ 1;
629 if (muiGlobalInfo(obj
)->mgi_Prefs
->window_redraw
== WINDOW_REDRAW_WITHOUT_CLEAR
)
630 backfill
= WA_BackFill
;
632 backfill
= TAG_IGNORE
;
634 if (muiGlobalInfo(obj
)->mgi_Prefs
->window_refresh
== WINDOW_REFRESH_SMART
)
635 flags
&= ~WFLG_SIMPLE_REFRESH
;
636 set(_app(obj
),MUIA_Application_SearchWinId
,data
->wd_ID
);
637 struct windowpos
*winp
=0;
638 get(_app(obj
),MUIA_Application_GetWinPos
,&winp
);
641 if (data
->wd_RenderInfo
.mri_ScreenWidth
> (data
->wd_X
+ data
->wd_Width
))
644 data
->wd_Width
=winp
->w1
;
646 if (data
->wd_RenderInfo
.mri_ScreenHeight
> (data
->wd_Y
+ data
->wd_Height
))
649 data
->wd_Height
=winp
->h1
;
654 gadgets
= (data
->wd_VertProp
!= NULL
) ? data
->wd_VertProp
: data
->wd_HorizProp
;
655 buttons
= muiGlobalInfo(obj
)->mgi_Prefs
->window_buttons
;
661 WA_Left
, (IPTR
) data
->wd_X
,
662 WA_Top
, (IPTR
) data
->wd_Y
,
663 WA_Flags
, (IPTR
) flags
,
666 TAG_IGNORE
, (IPTR
) data
->wd_Title
,
667 data
->wd_ScreenTitle
?
669 TAG_IGNORE
, (IPTR
) data
->wd_ScreenTitle
,
670 WA_CustomScreen
, (IPTR
) data
->wd_RenderInfo
.mri_Screen
,
671 WA_InnerWidth
, (IPTR
) data
->wd_Width
,
672 WA_InnerHeight
, (IPTR
) data
->wd_Height
,
673 WA_AutoAdjust
, (IPTR
) TRUE
,
674 WA_NewLookMenus
, (IPTR
) TRUE
,
676 WA_ToolBox
, (IPTR
) !!(data
->wd_Flags
& MUIWF_TOOLBOX
),
679 WA_ExtraGadget_MUI
, (IPTR
) ((buttons
& MUIV_Window_Button_MUI
) != 0) ? TRUE
: FALSE
,
680 WA_ExtraGadget_PopUp
, (IPTR
) ((buttons
& MUIV_Window_Button_Popup
) != 0) ? TRUE
: FALSE
,
681 WA_ExtraGadget_Snapshot
,(IPTR
) ((buttons
& MUIV_Window_Button_Snapshot
) != 0) ? TRUE
: FALSE
,
682 WA_ExtraGadget_Iconify
, (IPTR
) ((buttons
& MUIV_Window_Button_Iconify
) != 0) ? TRUE
: FALSE
,
686 TAG_IGNORE
, (IPTR
) TRUE
,
687 WA_Gadgets
, (IPTR
) gadgets
,
688 data
->wd_ZoomGadget
?
690 TAG_IGNORE
, (IPTR
) &altdims
,
691 backfill
, (IPTR
) LAYERS_NOBACKFILL
,
698 int hborders
= win
->BorderLeft
+ win
->BorderRight
;
699 int vborders
= win
->BorderTop
+ win
->BorderBottom
;
701 /* recalc window size (which will hopefully equal our requested size) */
702 data
->wd_Width
= win
->GZZWidth
;
703 data
->wd_Height
= win
->GZZHeight
;
705 /* set window limits according to window contents */
708 win
, data
->wd_MinMax
.MinWidth
+ hborders
,
709 data
->wd_MinMax
.MinHeight
+ vborders
,
710 data
->wd_MinMax
.MaxWidth
+ hborders
,
711 data
->wd_MinMax
.MaxHeight
+ vborders
714 win
->UserData
= (BYTE
*)data
->wd_RenderInfo
.mri_WindowObject
;
715 win
->UserPort
= muiGlobalInfo(obj
)->mgi_WindowsPort
; /* Same port for all windows */
716 ModifyIDCMP(win
, data
->wd_Events
);
718 data
->wd_RenderInfo
.mri_Window
= win
;
719 data
->wd_RenderInfo
.mri_VertProp
= data
->wd_VertProp
;
720 data
->wd_RenderInfo
.mri_HorizProp
= data
->wd_HorizProp
;
721 SetDrMd(win
->RPort
,JAM1
); //text is draw wrong in toolbarclass if not set
725 data
->wd_Menu
= menu
;
726 SetMenuStrip(win
,menu
);
729 if (flags
& WFLG_ACTIVATE
)
731 data
->wd_Flags
|= MUIWF_ACTIVE
;
737 if (menu
) FreeMenus(menu
);
738 UndisplayWindow(obj
, data
);
744 static void UndisplayWindow(Object
*obj
, struct MUI_WindowData
*data
)
746 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
747 if ((data
->wd_XStore
>= 0) && (data
->wd_YStore
>= 0))
749 DoMethod(obj
,MUIM_Window_Snapshot
,0);
752 data
->wd_RenderInfo
.mri_Window
= NULL
;
753 data
->wd_RenderInfo
.mri_VertProp
= NULL
;
754 data
->wd_RenderInfo
.mri_HorizProp
= NULL
;
756 data
->wd_Flags
&= ~MUIWF_ACTIVE
;
760 /* store position and size */
761 if (data
->wd_XStore
>=0)
762 data
->wd_X
= win
->LeftEdge
;
764 data
->wd_X
= data
->wd_XStore
;
765 if (data
->wd_YStore
>=0)
766 data
->wd_Y
= win
->TopEdge
;
768 data
->wd_Y
= data
->wd_YStore
;
769 data
->wd_Width
= win
->GZZWidth
;
770 data
->wd_Height
= win
->GZZHeight
;
775 FreeMenus(data
->wd_Menu
);
776 data
->wd_Menu
= NULL
;
781 struct IntuiMessage
*msg
, *succ
;
783 /* remove all messages pending for this window */
787 msg
= (struct IntuiMessage
*)win
->UserPort
->mp_MsgList
.lh_Head
;
788 (succ
= (struct IntuiMessage
*)msg
->ExecMessage
.mn_Node
.ln_Succ
);
792 if (msg
->IDCMPWindow
== win
)
794 Remove((struct Node
*)msg
);
795 ReplyMsg((struct Message
*)msg
);
798 win
->UserPort
= NULL
;
803 /* D(bug("before CloseWindow\n")); */
805 /* D(bug("after CloseWindow\n")); */
808 #define DISPOSEGADGET(x) \
811 DoMethod(obj, MUIM_Window_FreeGadgetID, ((struct Gadget*)x)->GadgetID);\
816 DISPOSEGADGET(data
->wd_VertProp
);
817 DISPOSEGADGET(data
->wd_UpButton
);
818 DISPOSEGADGET(data
->wd_DownButton
);
819 DISPOSEGADGET(data
->wd_HorizProp
);
820 DISPOSEGADGET(data
->wd_LeftButton
);
821 DISPOSEGADGET(data
->wd_RightButton
);
826 /* Initialize data->wd_X and data->wd_Y for DisplayWindow */
827 /* FIXME 20030817: needs some fixing, seems not fully implemented */
828 static void CalcWindowPosition(Object
*obj
, struct MUI_WindowData
*data
)
830 data
->wd_XStore
= data
->wd_X
;
831 data
->wd_YStore
= data
->wd_Y
;
832 if (NULL
== data
->wd_RefWindow
)
834 /* The following calculations are not very correct, the size and dragbar
835 ** are ignored also the current overscan view */
836 if (data
->wd_X
== MUIV_Window_LeftEdge_Centered
)
838 data
->wd_X
= (data
->wd_RenderInfo
.mri_Screen
->Width
- data
->wd_Width
)/2;
840 else if (data
->wd_X
== MUIV_Window_LeftEdge_Moused
)
842 data
->wd_X
= data
->wd_RenderInfo
.mri_Screen
->MouseX
;
845 if (data
->wd_Y
== MUIV_Window_TopEdge_Centered
)
847 data
->wd_Y
= (data
->wd_RenderInfo
.mri_Screen
->Height
- data
->wd_Height
)/2;
849 else if (data
->wd_Y
== MUIV_Window_TopEdge_Moused
)
851 data
->wd_Y
= data
->wd_RenderInfo
.mri_Screen
->MouseY
;
853 else if (data
->wd_Y
<= MUIV_Window_TopEdge_Delta(0))
855 data
->wd_Y
= data
->wd_RenderInfo
.mri_Screen
->BarHeight
+ 1
856 + MUIV_Window_TopEdge_Delta(0) - data
->wd_Y
;
864 get(data
->wd_RefWindow
, MUIA_Window_Width
, &w
);
865 get(data
->wd_RefWindow
, MUIA_Window_LeftEdge
, &x
);
867 if (data
->wd_X
== MUIV_Window_LeftEdge_Centered
)
869 data
->wd_X
= x
+ (w
- data
->wd_Width
)/2;
876 get(data
->wd_RefWindow
, MUIA_Window_Height
, &h
);
877 get(data
->wd_RefWindow
, MUIA_Window_TopEdge
, &y
);
879 if (data
->wd_Y
== MUIV_Window_TopEdge_Centered
)
881 /* D(bug("y=%ld, h=%ld, wdh=%ld\n", y, h, data->wd_Height)); */
882 data
->wd_Y
= y
+ (h
- data
->wd_Height
)/2;
884 else if (data
->wd_Y
<= MUIV_Window_TopEdge_Delta(0))
886 /* ??? surely incorrect implementation */
887 data
->wd_Y
= y
+ 1 + MUIV_Window_TopEdge_Delta(0) - data
->wd_Y
;
896 /* Initialize data->wd_AltDim for DisplayWindow */
897 static void CalcAltDimensions(Object
*obj
, struct MUI_WindowData
*data
)
899 /* Calculate alternate (zoomed) dimensions.
901 if (data
->wd_AltDim
.Top
== MUIV_Window_AltTopEdge_NoChange
)
902 data
->wd_AltDim
.Top
= ~0;
903 else if (data
->wd_AltDim
.Top
== MUIV_Window_AltTopEdge_Centered
)
904 data
->wd_AltDim
.Top
= (data
->wd_RenderInfo
.mri_Screen
->Height
- data
->wd_Height
)/2;
905 else if (data
->wd_AltDim
.Top
== MUIV_Window_AltTopEdge_Moused
)
906 /* ? */ data
->wd_AltDim
.Top
= ~0;
908 if (data
->wd_AltDim
.Left
== MUIV_Window_AltLeftEdge_NoChange
)
909 data
->wd_AltDim
.Left
= ~0;
910 else if (data
->wd_AltDim
.Left
== MUIV_Window_AltLeftEdge_Centered
)
911 data
->wd_AltDim
.Left
= (data
->wd_RenderInfo
.mri_Screen
->Width
- data
->wd_Width
)/2;
912 else if (data
->wd_AltDim
.Left
== MUIV_Window_AltLeftEdge_Moused
)
913 /* ? */ data
->wd_AltDim
.Left
= ~0;
919 MUIV_Window_AltWidth_MinMax(100),
920 data
->wd_AltDim
.Width
,
921 MUIV_Window_AltWidth_MinMax(0)
925 data
->wd_AltDim
.Width
= data
->wd_MinMax
.MinWidth
926 - data
->wd_AltDim
.Width
927 * (data
->wd_MinMax
.MaxWidth
- data
->wd_MinMax
.MinWidth
);
933 MUIV_Window_AltWidth_Screen(100),
934 data
->wd_AltDim
.Width
,
935 MUIV_Window_AltWidth_Screen(0)
939 data
->wd_AltDim
.Width
= data
->wd_RenderInfo
.mri_ScreenWidth
940 * (- (data
->wd_AltDim
.Width
+ 200)) / 100;
946 MUIV_Window_AltWidth_Visible(100),
947 data
->wd_AltDim
.Width
,
948 MUIV_Window_AltWidth_Visible(0)
952 data
->wd_AltDim
.Width
= data
->wd_RenderInfo
.mri_ScreenWidth
953 * (- (data
->wd_AltDim
.Width
+ 100)) / 100;
960 MUIV_Window_AltHeight_MinMax(100),
961 data
->wd_AltDim
.Height
,
962 MUIV_Window_AltHeight_MinMax(0)
966 data
->wd_AltDim
.Height
= data
->wd_MinMax
.MinHeight
967 - data
->wd_AltDim
.Height
968 * (data
->wd_MinMax
.MaxHeight
- data
->wd_MinMax
.MinHeight
);
974 MUIV_Window_AltHeight_Screen(100),
975 data
->wd_AltDim
.Height
,
976 MUIV_Window_AltHeight_Screen(0)
980 data
->wd_AltDim
.Height
= data
->wd_RenderInfo
.mri_ScreenHeight
981 * (- (data
->wd_AltDim
.Height
+ 200)) / 100;
987 MUIV_Window_AltHeight_Visible(100),
988 data
->wd_AltDim
.Height
,
989 MUIV_Window_AltHeight_Visible(0)
993 data
->wd_AltDim
.Height
= data
->wd_RenderInfo
.mri_ScreenHeight
994 * (- (data
->wd_AltDim
.Height
+ 100)) / 100;
997 data
->wd_AltDim
.Width
= CLAMP
999 data
->wd_AltDim
.Width
, data
->wd_MinMax
.MinWidth
,
1000 data
->wd_MinMax
.MaxWidth
1002 data
->wd_AltDim
.Height
= CLAMP
1004 data
->wd_AltDim
.Height
, data
->wd_MinMax
.MinHeight
,
1005 data
->wd_MinMax
.MaxHeight
1010 /* Create horiz/vert window scrollbars for DisplayWindow */
1011 static void CreateWindowScrollbars(Object
*obj
, struct MUI_WindowData
*data
)
1013 struct MUI_RenderInfo
*mri
= &data
->wd_RenderInfo
;
1014 Object
*firstgad
= NULL
;
1015 Object
*prevgad
= NULL
;
1018 /* Create the right border scrollers now if requested */
1019 if (data
->wd_Flags
& MUIWF_USERIGHTSCROLLER
)
1023 voffset
= IM(mri
->mri_DownImage
)->Width
/ 4;
1025 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1026 firstgad
= prevgad
= data
->wd_VertProp
= NewObject
1030 GA_RelRight
, 1 - (IM(mri
->mri_UpImage
)->Width
- voffset
),
1031 GA_Top
, mri
->mri_BorderTop
+ 2,
1032 GA_Width
, IM(mri
->mri_UpImage
)->Width
- voffset
* 2,
1033 GA_RelHeight
, - (mri
->mri_BorderTop
+ 2)
1034 - IM(mri
->mri_UpImage
)->Height
1035 - IM(mri
->mri_DownImage
)->Height
1036 - IM(mri
->mri_SizeImage
)->Height
- 2,
1037 GA_RightBorder
, TRUE
,
1039 PGA_Borderless
, TRUE
,
1041 PGA_Freedom
, FREEVERT
,
1045 ICA_TARGET
, ICTARGET_IDCMP
,
1049 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1050 prevgad
= data
->wd_UpButton
= NewObject
1052 NULL
, "buttongclass",
1054 GA_Image
, (IPTR
)mri
->mri_UpImage
,
1055 GA_RelRight
, 1 - IM(mri
->mri_UpImage
)->Width
,
1056 GA_RelBottom
, 1 - IM(mri
->mri_UpImage
)->Height
1057 - IM(mri
->mri_DownImage
)->Height
1058 - IM(mri
->mri_SizeImage
)->Height
,
1059 GA_RightBorder
, TRUE
,
1060 GA_Previous
, (IPTR
)prevgad
,
1062 ICA_TARGET
, ICTARGET_IDCMP
,
1066 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1067 prevgad
= data
->wd_DownButton
= NewObject
1069 NULL
, "buttongclass",
1071 GA_Image
, (IPTR
)mri
->mri_DownImage
,
1072 GA_RelRight
, 1 - IM(mri
->mri_DownImage
)->Width
,
1073 GA_RelBottom
, 1 - IM(mri
->mri_DownImage
)->Height
1074 - IM(mri
->mri_SizeImage
)->Height
,
1075 GA_RightBorder
, TRUE
,
1076 GA_Previous
, (IPTR
)prevgad
,
1078 ICA_TARGET
, ICTARGET_IDCMP
,
1081 } // if (data->wd_Flags & MUIWF_USERIGHTSCROLLER)
1083 /* Create the bottom border scrollers now if requested */
1084 if (data
->wd_Flags
& MUIWF_USEBOTTOMSCROLLER
)
1088 hoffset
= IM(mri
->mri_RightImage
)->Height
/ 4;
1090 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1091 prevgad
= data
->wd_HorizProp
= NewObject
1095 GA_RelBottom
, 1 - (IM(mri
->mri_LeftImage
)->Height
- hoffset
),
1096 GA_Left
, mri
->mri_BorderLeft
,
1097 GA_Height
, IM(mri
->mri_LeftImage
)->Height
1099 GA_RelWidth
, - (mri
->mri_BorderLeft
)
1100 - IM(mri
->mri_LeftImage
)->Width
1101 - IM(mri
->mri_RightImage
)->Width
1102 - IM(mri
->mri_SizeImage
)->Width
1104 GA_BottomBorder
, TRUE
,
1106 prevgad
? GA_Previous
: TAG_IGNORE
, (IPTR
)prevgad
,
1107 PGA_Borderless
, TRUE
,
1109 PGA_Freedom
, FREEHORIZ
,
1113 ICA_TARGET
, ICTARGET_IDCMP
,
1117 if (!firstgad
) firstgad
= prevgad
;
1119 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1120 prevgad
= data
->wd_LeftButton
= NewObject
1122 NULL
, "buttongclass",
1124 GA_Image
, (IPTR
)mri
->mri_LeftImage
,
1125 GA_RelRight
, 1 - IM(mri
->mri_LeftImage
)->Width
1126 - IM(mri
->mri_RightImage
)->Width
1127 - IM(mri
->mri_SizeImage
)->Width
,
1128 GA_RelBottom
, 1 - IM(mri
->mri_LeftImage
)->Height
,
1129 GA_BottomBorder
, TRUE
,
1130 GA_Previous
, (IPTR
)prevgad
,
1132 ICA_TARGET
, ICTARGET_IDCMP
,
1136 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1137 prevgad
= data
->wd_RightButton
= NewObject
1139 NULL
, "buttongclass",
1141 GA_Image
, (IPTR
)mri
->mri_RightImage
,
1142 GA_RelRight
, 1 - IM(mri
->mri_RightImage
)->Width
1143 - IM(mri
->mri_SizeImage
)->Width
,
1144 GA_RelBottom
, 1 - IM(mri
->mri_RightImage
)->Height
,
1145 GA_BottomBorder
, TRUE
,
1146 GA_Previous
, (IPTR
)prevgad
,
1148 ICA_TARGET
, ICTARGET_IDCMP
,
1150 } // if (data->wd_Flags & MUIWF_USEBOTTOMSCROLLER)
1153 /* return FALSE only if no resize (dx=dy=0) occured */
1154 static BOOL
WindowResize (struct MUI_WindowData
*data
)
1156 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
1157 int hborders
= win
->BorderLeft
+ win
->BorderRight
;
1158 int vborders
= win
->BorderTop
+ win
->BorderBottom
;
1159 WORD dx
= data
->wd_Width
- win
->Width
+ hborders
;
1160 WORD dy
= data
->wd_Height
- win
->Height
+ vborders
;
1162 /* Temporarily disable window limits to let SizeWindow below work
1163 regardless of the previous limits */
1171 /* D(bug("_zune_window_resize : dx=%d, dy=%d\n", dx, dy)); */
1172 SizeWindow(win
, dx
, dy
);
1174 /* Set new window limits */
1177 win
, data
->wd_MinMax
.MinWidth
+ hborders
,
1178 data
->wd_MinMax
.MinHeight
+ vborders
,
1179 data
->wd_MinMax
.MaxWidth
+ hborders
,
1180 data
->wd_MinMax
.MaxHeight
+ vborders
1186 static void KillHelpBubble(struct MUI_WindowData
*data
, Object
*obj
, BOOL kill_bubblemode
)
1188 if (data
->wd_HelpObject
)
1190 DoMethod(data
->wd_HelpObject
, MUIM_DeleteBubble
, (IPTR
)data
->wd_HelpBubble
);
1191 data
->wd_HelpObject
= NULL
;
1192 data
->wd_HelpBubble
= NULL
;
1195 if (kill_bubblemode
) data
->wd_Flags
&= ~MUIWF_BUBBLEMODE
;
1197 if (data
->wd_Flags
& MUIWF_BUBBLEMODE
)
1199 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_LATER
;
1203 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_FIRST
;
1210 typedef BOOL (*UNDERCHECK_FUNC
)(Object
*obj
);
1212 static BOOL
ShortHelpUnderPointerCheck(Object
*obj
)
1214 return muiAreaData(obj
)->mad_ShortHelp
? TRUE
: FALSE
;
1217 static Object
*ObjectUnderPointer(struct MUI_WindowData
*data
, Object
*obj
,
1218 LONG x
, LONG y
, UNDERCHECK_FUNC func
)
1222 struct MinList
*ChildList
= NULL
;
1224 if (!(muiAreaData(obj
)->mad_Flags
& MADF_CANDRAW
))
1227 if (!(x
>= _left(obj
) && x
<= _right(obj
)
1228 && y
>= _top(obj
) && y
<= _bottom(obj
)))
1233 if ((get(obj
, MUIA_Group_ChildList
, &(ChildList
))) && (ChildList
!= NULL
))
1235 cstate
= (Object
*)ChildList
->mlh_Head
;
1236 while ((child
= NextObject(&cstate
)))
1240 if ((x
>= _left(child
) && x
<= _right(child
)
1242 y
>= _top(child
) && y
<= _bottom(child
))
1244 (ret
= ObjectUnderPointer(data
, child
, x
, y
, func
)))
1251 if (!(*func
)(obj
)) return NULL
;
1256 static BOOL
ContextMenuUnderPointer(struct MUI_WindowData
*data
, Object
*obj
, LONG x
, LONG y
)
1260 struct MinList
*ChildList
= NULL
;
1262 if (!(x
>= _left(obj
) && x
<= _right(obj
)
1263 && y
>= _top(obj
) && y
<= _bottom(obj
)))
1268 if ((get(obj
, MUIA_Group_ChildList
, &(ChildList
))) && (ChildList
!= NULL
))
1271 cstate
= (Object
*)ChildList
->mlh_Head
;
1272 while ((child
= NextObject(&cstate
)))
1274 if ((x
>= _left(child
) && x
<= _right(child
)
1276 y
>= _top(child
) && y
<= _bottom(child
))
1278 (ContextMenuUnderPointer(data
,child
,x
,y
)))
1283 if (!(muiAreaData(obj
)->mad_Flags
& MADF_CANDRAW
))
1285 if (!(muiAreaData(obj
)->mad_ContextMenu
))
1293 static void ActivateObject (struct MUI_WindowData
*data
)
1295 //bug("Window::ActivateObject (dummy) %08lx\n", data->wd_ActiveObject);
1296 // if (FindObjNode(&data->wd_CycleChain, data->wd_ActiveObject))
1297 // DoMethod(data->wd_ActiveObject, MUIM_GoActive);
1299 // data->wd_ActiveObject = NULL;
1300 //activate better string gadgets.Fix from Georg S On ML List
1301 if (FindObjNode(&data
->wd_CycleChain
, data
->wd_ActiveObject
))
1303 if (!(data
->wd_Flags
& MUIWF_OBJECTGOACTIVESENT
))
1305 data
->wd_Flags
|= MUIWF_OBJECTGOACTIVESENT
;
1306 DoMethod(data
->wd_ActiveObject
, MUIM_GoActive
);
1310 data
->wd_ActiveObject
= NULL
;
1316 static void HandleInputEvent(Object
*win
, struct MUI_WindowData
*data
,
1317 struct IntuiMessage
*event
);
1319 /* handle intuimessage while an object is being dragged
1320 * (reply imsg before returning)
1322 void HandleDragging (Object
*oWin
, struct MUI_WindowData
*data
,
1323 struct IntuiMessage
*imsg
)
1325 struct Window
*iWin
;
1326 int finish_drag
= 0;
1328 iWin
= imsg
->IDCMPWindow
;
1330 if (imsg
->Class
== IDCMP_MOUSEMOVE
)
1332 struct Layer
*layer
;
1333 layer
= WhichLayer(&iWin
->WScreen
->LayerInfo
, iWin
->LeftEdge
+ imsg
->MouseX
, iWin
->TopEdge
+ imsg
->MouseY
);
1335 if (data
->wd_DropObject
)
1338 WORD mousex
= imsg
->MouseX
+ iWin
->LeftEdge
- data
->wd_DropWindow
->LeftEdge
;
1339 WORD mousey
= imsg
->MouseY
+ iWin
->TopEdge
- data
->wd_DropWindow
->TopEdge
;
1341 wnd
= _window(data
->wd_DropObject
);
1344 mousex
< _left(data
->wd_DropObject
)
1345 || mousex
> _right(data
->wd_DropObject
)
1346 || mousey
< _top(data
->wd_DropObject
)
1347 || mousey
> _bottom(data
->wd_DropObject
)
1348 || layer
!= wnd
->WLayer
1351 /* We have left the object */
1352 UndrawDragNDrop(data
->wd_dnd
);
1353 DoMethod(data
->wd_DropObject
, MUIM_DragFinish
,(IPTR
)data
->wd_DragObject
);
1354 data
->wd_DropObject
= NULL
;
1356 } /* if (data->wd_DropObject) */
1358 if (!data
->wd_DropObject
)
1360 Object
*dest_wnd
= NULL
;
1362 /* Find out if app has an openend window at this position */
1367 struct MinList
*ChildList
;
1369 get(_app(oWin
), MUIA_Application_WindowList
, &(ChildList
));
1370 cstate
= (Object
*)ChildList
->mlh_Head
;
1371 while ((child
= NextObject(&cstate
)))
1374 get(child
, MUIA_Window_Window
,&wnd
);
1377 if (wnd
->WLayer
== layer
)
1379 data
->wd_DropWindow
= wnd
;
1389 get(dest_wnd
, MUIA_Window_RootObject
, &root
);
1396 data
->wd_DropObject
= (Object
*) DoMethod
1398 root
, MUIM_DragQueryExtended
,
1399 (IPTR
) data
->wd_DragObject
,
1400 imsg
->MouseX
+ iWin
->LeftEdge
- data
->wd_DropWindow
->LeftEdge
,
1401 imsg
->MouseY
+ iWin
->TopEdge
- data
->wd_DropWindow
->TopEdge
1406 UndrawDragNDrop(data
->wd_dnd
);
1407 DoMethod(data
->wd_DropObject
, MUIM_DragBegin
,(IPTR
)data
->wd_DragObject
);
1410 } /* if (dest_wnd) */
1411 } /* if (!data->wd_DropObject) */
1413 if (data
->wd_DropObject
)
1421 data
->wd_DropObject
, MUIM_DragReport
,
1422 (IPTR
) data
->wd_DragObject
,
1423 imsg
->MouseX
+ iWin
->LeftEdge
- data
->wd_DropWindow
->LeftEdge
,
1424 imsg
->MouseY
+ iWin
->TopEdge
- data
->wd_DropWindow
->TopEdge
,update
1428 case MUIV_DragReport_Abort
:
1429 UndrawDragNDrop(data
->wd_dnd
);
1430 DoMethod(data
->wd_DropObject
, MUIM_DragFinish
,(IPTR
)data
->wd_DragObject
);
1431 data
->wd_DropObject
= NULL
;
1435 case MUIV_DragReport_Continue
: break;
1436 case MUIV_DragReport_Lock
: break; /* NYI */
1437 case MUIV_DragReport_Refresh
:
1438 UndrawDragNDrop(data
->wd_dnd
);
1443 } /* if (data->wd_DropObject) */
1444 DrawDragNDrop(data
->wd_dnd
, imsg
->MouseX
+ iWin
->LeftEdge
, imsg
->MouseY
+ iWin
->TopEdge
);
1445 } /* if (imsg->Class == IDCMP_MOUSEMOVE) */
1447 if (imsg
->Class
== IDCMP_MOUSEBUTTONS
)
1449 if ((imsg
->Code
== MENUDOWN
) || (imsg
->Code
== SELECTUP
))
1451 if (imsg
->Code
== SELECTUP
&& data
->wd_DropObject
)
1453 UndrawDragNDrop(data
->wd_dnd
);
1454 DoMethod(data
->wd_DropObject
, MUIM_DragFinish
, (IPTR
)data
->wd_DragObject
);
1457 data
->wd_DropObject
, MUIM_DragDrop
, (IPTR
)data
->wd_DragObject
,
1458 imsg
->MouseX
+ iWin
->LeftEdge
- data
->wd_DropWindow
->LeftEdge
,
1459 imsg
->MouseY
+ iWin
->TopEdge
- data
->wd_DropWindow
->TopEdge
1461 data
->wd_DropObject
= NULL
;
1463 else if (imsg
->Code
== SELECTUP
)
1465 DoMethod(data
->wd_DragObject
, MUIM_UnknownDropDestination
, imsg
);
1471 if (imsg
->Class
== IDCMP_CLOSEWINDOW
)
1476 UndrawDragNDrop(data
->wd_dnd
);
1477 if (data
->wd_DropObject
)
1479 DoMethod(data
->wd_DropObject
, MUIM_DragFinish
,(IPTR
)data
->wd_DragObject
);
1480 data
->wd_DropObject
= NULL
;
1482 DeleteDragNDrop(data
->wd_dnd
);
1483 DoMethod(data
->wd_DragObject
,MUIM_DeleteDragImage
, (IPTR
)data
->wd_DragImage
);
1484 muiAreaData(data
->wd_DragObject
)->mad_Flags
&= ~MADF_DRAGGING
;
1485 data
->wd_DragImage
= NULL
;
1486 data
->wd_DragObject
= NULL
;
1487 data
->wd_DropWindow
= NULL
;
1488 data
->wd_dnd
= NULL
;
1489 /* stop listening to IDCMP_MOUSEMOVE */
1490 ChangeEvents(data
, GetDefaultEvents());
1492 ReplyMsg((struct Message
*)imsg
);
1495 /* Reply to imsg if handled */
1496 BOOL
HandleWindowEvent (Object
*oWin
, struct MUI_WindowData
*data
,
1497 struct IntuiMessage
*imsg
)
1499 struct Window
*iWin
;
1500 BOOL is_handled
= TRUE
;
1501 BOOL replied
= FALSE
;
1503 iWin
= imsg
->IDCMPWindow
;
1504 switch (imsg
->Class
)
1506 case IDCMP_ACTIVEWINDOW
:
1507 data
->wd_Flags
|= MUIWF_ACTIVE
;
1508 if (data
->wd_OldActive
)
1509 set(oWin
, MUIA_Window_ActiveObject
, data
->wd_OldActive
);
1510 set(oWin
, MUIA_Window_Activate
, TRUE
);
1511 is_handled
= FALSE
; /* forwardable to area event handlers */
1514 case IDCMP_INACTIVEWINDOW
:
1515 KillHelpBubble(data
, oWin
, TRUE
);
1516 if (data
->wd_ActiveObject
)
1518 data
->wd_OldActive
= data
->wd_ActiveObject
;
1519 set(oWin
, MUIA_Window_ActiveObject
, MUIV_Window_ActiveObject_None
);
1521 data
->wd_Flags
&= ~MUIWF_ACTIVE
;
1522 set(oWin
, MUIA_Window_Activate
, FALSE
);
1523 is_handled
= FALSE
; /* forwardable to area event handlers */
1527 ReplyMsg((struct Message
*)imsg
);
1531 int hborders
= iWin
->BorderLeft
+ iWin
->BorderRight
;
1532 int vborders
= iWin
->BorderTop
+ iWin
->BorderBottom
;
1534 /* set window limits according to window contents */
1537 data
->wd_MinMax
.MinWidth
+ hborders
,
1538 data
->wd_MinMax
.MinHeight
+ vborders
,
1539 data
->wd_MinMax
.MaxWidth
+ hborders
,
1540 data
->wd_MinMax
.MaxHeight
+ vborders
1544 if ((iWin
->GZZWidth
!= data
->wd_Width
) || (iWin
->GZZHeight
!= data
->wd_Height
))
1546 data
->wd_Width
= iWin
->GZZWidth
;
1547 data
->wd_Height
= iWin
->GZZHeight
;
1548 DoHideMethod(data
->wd_RootObject
);
1550 if (1) // why only simple refresh? was: if (data->wd_RenderInfo.mri_Window->Flags & WFLG_SIMPLE_REFRESH)
1552 data
->wd_Flags
|= MUIWF_RESIZING
;
1556 _width(data
->wd_RootObject
) = data
->wd_Width
;
1557 _height(data
->wd_RootObject
) = data
->wd_Height
;
1558 DoMethod(data
->wd_RootObject
, MUIM_Layout
);
1559 DoShowMethod(data
->wd_RootObject
);
1561 LONG left
,top
,width
,height
;
1563 left
= data
->wd_RenderInfo
.mri_Window
->BorderLeft
;
1564 top
= data
->wd_RenderInfo
.mri_Window
->BorderTop
,
1565 width
= data
->wd_RenderInfo
.mri_Window
->Width
1566 - data
->wd_RenderInfo
.mri_Window
->BorderRight
- left
;
1567 height
= data
->wd_RenderInfo
.mri_Window
->Height
1568 - data
->wd_RenderInfo
.mri_Window
->BorderBottom
- top
;
1570 // D(bug("%d:zune_imspec_draw(%p) l=%d t=%d w=%d h=%d xo=%d yo=%d\n",
1571 // __LINE__, data->wd_Background, left, top, width,
1572 // height, left, top));
1573 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
1574 left
, top
, width
, height
, left
, top
, 0);
1576 if (muiGlobalInfo(oWin
)->mgi_Prefs
->window_redraw
== WINDOW_REDRAW_WITHOUT_CLEAR
)
1577 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWOBJECT
);
1579 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWALL
);
1580 // but should only draw focus without using MUIM_GoActive !
1581 ActivateObject(data
);
1586 case IDCMP_REFRESHWINDOW
:
1587 ReplyMsg((struct Message
*)imsg
);
1589 if (data
->wd_Flags
& MUIWF_RESIZING
)
1591 //LONG left,top,right,bottom;
1592 if (MUI_BeginRefresh(&data
->wd_RenderInfo
, 0))
1594 MUI_EndRefresh(&data
->wd_RenderInfo
, 0);
1596 RefreshWindowFrame(data
->wd_RenderInfo
.mri_Window
);
1598 data
->wd_Flags
&= ~MUIWF_RESIZING
;
1599 _width(data
->wd_RootObject
) = data
->wd_Width
;
1600 _height(data
->wd_RootObject
) = data
->wd_Height
;
1601 DoMethod(data
->wd_RootObject
, MUIM_Layout
);
1602 DoShowMethod(data
->wd_RootObject
);
1604 if (muiGlobalInfo(oWin
)->mgi_Prefs
->window_redraw
== WINDOW_REDRAW_WITH_CLEAR
)
1606 LONG left
,top
,width
,height
;
1608 left
= data
->wd_RenderInfo
.mri_Window
->BorderLeft
;
1609 top
= data
->wd_RenderInfo
.mri_Window
->BorderTop
,
1610 width
= data
->wd_RenderInfo
.mri_Window
->Width
- data
->wd_RenderInfo
.mri_Window
->BorderRight
- left
;
1611 height
= data
->wd_RenderInfo
.mri_Window
->Height
- data
->wd_RenderInfo
.mri_Window
->BorderBottom
- top
;
1613 if(data
->wd_Flags
& MUIWF_ERASEAREA
)
1615 // D(bug("%d:zune_imspec_draw(%p) l=%d t=%d w=%d h=%d xo=%d yo=%d\n",
1616 // __LINE__, data->wd_Background, left, top, width,
1617 // height, left, top));
1618 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
1619 left
, top
, width
, height
, left
, top
, 0);
1621 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWALL
);
1624 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWOBJECT
);
1625 // but should only draw focus without using MUIM_GoActive !
1626 ActivateObject(data
);
1630 if (MUI_BeginRefresh(&data
->wd_RenderInfo
, 0))
1632 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWALL
);
1633 // but should only draw focus without using MUIM_GoActive !
1634 ActivateObject(data
);
1635 MUI_EndRefresh(&data
->wd_RenderInfo
, 0);
1640 case IDCMP_CLOSEWINDOW
:
1641 ReplyMsg((struct Message
*)imsg
);
1643 set(oWin
, MUIA_Window_CloseRequest
, TRUE
);
1646 case IDCMP_MENUPICK
:
1647 ReplyMsg((struct Message
*)imsg
);
1652 if (MENUNUM(imsg
->Code
) != NOMENU
&& ITEMNUM(imsg
->Code
) != NOITEM
)
1654 struct MenuItem
*item
= ItemAddress(data
->wd_Menu
,imsg
->Code
);
1657 Object
*item_obj
= (Object
*)GTMENUITEM_USERDATA(item
);
1663 if (item
->Flags
& CHECKIT
)
1664 set(item_obj
, MUIA_Menuitem_Checked
, !!(item
->Flags
& CHECKED
));
1666 set(item_obj
, MUIA_Menuitem_Trigger
, (IPTR
)item
);
1668 get(oWin
, MUIA_ApplicationObject
, &app
);
1669 get(item_obj
, MUIA_UserData
, &udata
);
1671 set(app
, MUIA_Application_MenuAction
, udata
);
1672 set(oWin
, MUIA_Window_MenuAction
, udata
);
1673 DoMethod(app
, MUIM_Application_ReturnID
, udata
);
1680 case IDCMP_IDCMPUPDATE
:
1681 is_handled
= FALSE
; /* forwardable to area event handlers */
1682 if (data
->wd_VertProp
|| data
->wd_HorizProp
)
1684 struct TagItem
*tag
;
1685 tag
= FindTagItem(GA_ID
,(struct TagItem
*)imsg
->IAddress
);
1688 /* If there's a propclass object connected to the prop
1689 gadget, the prop gadget's userdata will point to
1690 that propclass object. See classes/prop.c */
1692 if (data
->wd_VertProp
)
1694 if (tag
->ti_Data
== GADGETID(data
->wd_VertProp
))
1697 if (tag
->ti_Data
== GADGETID(data
->wd_UpButton
))
1699 Object
*prop
= (Object
*)((struct Gadget
*)data
->wd_VertProp
)->UserData
;
1701 if (prop
) DoMethod(prop
, MUIM_Prop_Decrease
, 1);
1704 if (tag
->ti_Data
== GADGETID(data
->wd_DownButton
))
1706 Object
*prop
= (Object
*)((struct Gadget
*)data
->wd_VertProp
)->UserData
;
1708 if (prop
) DoMethod(prop
, MUIM_Prop_Increase
, 1);
1713 if (data
->wd_HorizProp
)
1715 if (tag
->ti_Data
== GADGETID(data
->wd_HorizProp
))
1718 if (tag
->ti_Data
== GADGETID(data
->wd_LeftButton
))
1720 Object
*prop
= (Object
*)((struct Gadget
*)data
->wd_HorizProp
)->UserData
;
1722 if (prop
) DoMethod(prop
, MUIM_Prop_Decrease
, 1);
1725 if (tag
->ti_Data
== GADGETID(data
->wd_RightButton
))
1727 Object
*prop
= (Object
*)((struct Gadget
*)data
->wd_HorizProp
)->UserData
;
1729 if (prop
) DoMethod(prop
, MUIM_Prop_Increase
, 1);
1737 case IDCMP_INTUITICKS
:
1738 if (data
->wd_HelpTicker
)
1740 data
->wd_HelpTicker
--;
1742 if (data
->wd_HelpTicker
== 0)
1744 Object
*underobj
= ObjectUnderPointer(data
, data
->wd_RootObject
, imsg
->MouseX
, imsg
->MouseY
,
1745 ShortHelpUnderPointerCheck
);
1747 if (underobj
!= data
->wd_HelpObject
)
1749 if (data
->wd_HelpObject
)
1751 DoMethod(data
->wd_HelpObject
, MUIM_DeleteBubble
, (IPTR
)data
->wd_HelpBubble
);
1753 data
->wd_HelpObject
= NULL
;
1754 data
->wd_HelpBubble
= NULL
;
1759 data
->wd_HelpBubble
= (APTR
)DoMethod(underobj
, MUIM_CreateBubble
,
1760 imsg
->MouseX
, imsg
->MouseY
,
1762 if (data
->wd_HelpBubble
)
1764 data
->wd_HelpObject
= underobj
;
1765 data
->wd_Flags
|= MUIWF_BUBBLEMODE
;
1770 if (data
->wd_Flags
& MUIWF_BUBBLEMODE
)
1772 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_LATER
;
1776 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_FIRST
;
1779 } /* if (data->wd_HelpTicker == 0) */
1781 } /* if (data->wd_HelpTicker) */
1783 is_handled
= FALSE
; /* forwardable to area event handlers */
1786 case IDCMP_MOUSEBUTTONS
:
1787 DoMethod(oWin
,MUIM_Window_Snapshot
,0);
1788 KillHelpBubble(data
, oWin
, TRUE
);
1793 case IDCMP_MOUSEMOVE
:
1794 KillHelpBubble(data
, oWin
, FALSE
);
1801 } /* switch (imsg->Class) */
1803 if (is_handled
&& !replied
)
1804 ReplyMsg((struct Message
*)imsg
);
1809 static ULONG
InvokeEventHandler (struct MUI_EventHandlerNode
*ehn
,
1810 struct IntuiMessage
*event
, ULONG muikey
)
1814 if (!(_flags(ehn
->ehn_Object
) & MADF_CANDRAW
)) return 0;
1815 if (!(_flags(ehn
->ehn_Object
) & MADF_SHOWME
)) return 0;
1820 && event
->Class
== IDCMP_MOUSEBUTTONS
1821 && event
->Code
== SELECTDOWN
1822 && (_flags(ehn
->ehn_Object
) & MADF_INVIRTUALGROUP
)
1826 Here we filter out SELECTDOWN messages if objects is in a virtual
1827 group but the click went out of the virtual group
1829 Object
*obj
= ehn
->ehn_Object
;
1830 Object
*parent
= obj
;
1831 Object
*wnd
= _win(obj
);
1833 while (get(parent
,MUIA_Parent
,&parent
))
1836 if (wnd
== parent
) break;
1837 if (_flags(parent
) & MADF_ISVIRTUALGROUP
)
1841 event
->MouseX
< _mleft(parent
)
1842 || event
->MouseX
> _mright(parent
)
1843 || event
->MouseY
< _mtop(parent
)
1844 || event
->MouseY
> _mbottom(parent
)
1854 if (ehn
->ehn_Flags
& MUI_EHF_HANDLEINPUT
)
1856 DoMethod(ehn
->ehn_Object
, MUIM_HandleInput
, (IPTR
)event
, muikey
);
1864 ehn
->ehn_Class
, ehn
->ehn_Object
, MUIM_HandleEvent
,
1868 res
= DoMethod(ehn
->ehn_Object
, MUIM_HandleEvent
, (IPTR
)event
, muikey
);
1873 static void HandleRawkey(Object
*win
, struct MUI_WindowData
*data
,
1874 struct IntuiMessage
*event
)
1877 struct MUI_EventHandlerNode
*ehn
;
1878 struct IntuiMessage imsg_copy
;
1879 struct InputEvent ie
= {0};
1881 LONG muikey
= MUIKEY_NONE
;
1882 Object
*active_object
= NULL
;
1887 KillHelpBubble(data
, win
, BUBBLEHELP_TICKER_FIRST
);
1889 ie
.ie_NextEvent
= NULL
;
1890 ie
.ie_Class
= IECLASS_RAWKEY
;
1892 ie
.ie_Code
= event
->Code
;
1893 ie
.ie_Qualifier
= event
->Qualifier
;
1894 ie
.ie_EventAddress
= (APTR
)*(ULONG
*)event
->IAddress
;
1896 ie
.ie_TimeStamp
.Seconds
= event
->Seconds
;
1897 ie
.ie_TimeStamp
.Microseconds
= event
->Micros
;
1899 ie
.ie_TimeStamp
.tv_secs
= event
->Seconds
;
1900 ie
.ie_TimeStamp
.tv_micro
= event
->Micros
;
1903 set(win
, MUIA_Window_InputEvent
, (IPTR
)&ie
);
1905 /* get the vanilla key for control char */
1908 /* Remove the up prefix as convert key does not convert a upkey event */
1909 msg_code
= event
->Code
;
1910 event
->Code
&= ~IECODE_UP_PREFIX
;
1911 key
= ConvertKey(event
);
1912 event
->Code
= msg_code
;
1916 deadkey
= *(ULONG
*)event
->IAddress
;
1917 imsg_copy
.IAddress
= &deadkey
;
1918 ReplyMsg((struct Message
*)event
);
1921 //bug("rawkey: code=%lx, qual=%lx\n", event->Code, event->Qualifier);
1923 /* check if imsg translate to predefined keystroke */
1925 struct InputEvent ievent
;
1926 BOOL matched
= FALSE
;
1928 ievent
.ie_NextEvent
= NULL
;
1929 ievent
.ie_Class
= IECLASS_RAWKEY
;
1930 ievent
.ie_SubClass
= 0;
1931 ievent
.ie_Code
= event
->Code
;
1932 ievent
.ie_Qualifier
= event
->Qualifier
;
1933 /* ie_EventAddress is not used by MatchIX. If needed, it should be
1934 * ensured that it is still a valid adress because of the shallow
1935 * IntuiMessage copy currently done in _zune_window_message before
1936 * message is replied.
1938 ievent
.ie_EventAddress
= NULL
;
1939 //ievent.ie_EventAddress = (APTR *) *((ULONG *)(event->IAddress));
1941 for (muikey
= MUIKEY_COUNT
- 1; muikey
>= MUIKEY_PRESS
; muikey
--)
1943 if (muiGlobalInfo(win
)->mgi_Prefs
->muikeys
[muikey
].ix_well
!= 0
1944 && MatchIX(&ievent
, &muiGlobalInfo(win
)->mgi_Prefs
->muikeys
[muikey
].ix
))
1953 if (muikey
== MUIKEY_PRESS
&& (event
->Code
& IECODE_UP_PREFIX
))
1954 muikey
= MUIKEY_RELEASE
;
1958 muikey
= MUIKEY_NONE
;
1960 } /* check if imsg translate to predefined keystroke */
1962 if ((muikey
!= MUIKEY_NONE
)
1963 && !(data
->wd_DisabledKeys
& (1<<muikey
)))
1965 D(bug("HandleRawkey: try MUIKEY %ld on window %0x08lx\n", muikey
, win
));
1968 case MUIKEY_PRESS
: break;
1969 case MUIKEY_TOGGLE
: break;
1970 case MUIKEY_UP
: break;
1971 case MUIKEY_DOWN
: break;
1972 case MUIKEY_PAGEUP
: break;
1973 case MUIKEY_PAGEDOWN
: break;
1974 case MUIKEY_TOP
: break;
1975 case MUIKEY_BOTTOM
: break;
1976 case MUIKEY_LEFT
: break;
1977 case MUIKEY_RIGHT
: break;
1978 case MUIKEY_WORDLEFT
: break;
1979 case MUIKEY_WORDRIGHT
: break;
1980 case MUIKEY_LINESTART
: break;
1981 case MUIKEY_LINEEND
: break;
1982 case MUIKEY_GADGET_NEXT
:
1983 set(win
, MUIA_Window_ActiveObject
, MUIV_Window_ActiveObject_Next
);
1985 case MUIKEY_GADGET_PREV
:
1986 set(win
, MUIA_Window_ActiveObject
, MUIV_Window_ActiveObject_Prev
);
1988 case MUIKEY_GADGET_OFF
:
1989 set(win
, MUIA_Window_ActiveObject
, MUIV_Window_ActiveObject_None
);
1991 case MUIKEY_WINDOW_CLOSE
:
1992 set(win
, MUIA_Window_CloseRequest
, TRUE
);
1994 case MUIKEY_WINDOW_NEXT
: break;
1995 case MUIKEY_WINDOW_PREV
: break;
1996 case MUIKEY_HELP
: break;
1997 case MUIKEY_POPUP
: break;
2002 active_object
= NULL
;
2003 if ((data
->wd_ActiveObject
!= NULL
)
2004 && (DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
2005 (IPTR
)data
->wd_ActiveObject
) != (IPTR
)NULL
))
2007 active_object
= data
->wd_ActiveObject
;
2008 get(active_object
, MUIA_Disabled
, &disabled
);
2011 data
->wd_ActiveObject
= NULL
;
2013 /* try ActiveObject */
2014 if ((active_object
!= NULL
) && !disabled
)
2018 ** Which method should be used for muikeys? MUIM_HandleInput or
2019 ** MUIM_HandleEvent. Also note that there is a flag MUI_EHF_ALWAYSKEYS
2020 ** which probably means that all keys events are requested??
2021 ** For now MUIM_HandleEvent is used as this is currently implemented
2022 ** in Area class ;) although I guess it should be MUIM_HandleInput as this
2026 if (muikey
!= MUIKEY_NONE
)
2028 res
= DoMethod(active_object
, MUIM_HandleEvent
, (IPTR
)event
, muikey
);
2029 if (res
& MUI_EventHandlerRC_Eat
) return;
2032 D(bug("HandleRawkey: try active object (%08lx) handlers\n", active_object
));
2034 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2036 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2038 if ((ehn
->ehn_Object
== active_object
)
2039 && ((ehn
->ehn_Events
& IDCMP_RAWKEY
)
2040 || (ehn
->ehn_Flags
& MUI_EHF_ALWAYSKEYS
)))
2042 D(bug("HandleRawkey: (active) invoking on %p (ehn=%p) event=%p muikey=%p\n",
2043 ehn
->ehn_Object
, ehn
, event
, muikey
));
2044 res
= InvokeEventHandler(ehn
, event
, muikey
);
2045 D(bug("HandleRawkey: (active) got res=%d\n", res
));
2046 if (res
& MUI_EventHandlerRC_Eat
)
2049 /* Leave the loop if a different object has been activated */
2050 if (active_object
!= data
->wd_ActiveObject
)
2053 } /* for (mn = data->wd_EHList.mlh_Head; mn->mln_Succ; mn = mn->mln_Succ) */
2055 // event not eaten by active object, try its parents
2056 // this is to implement popup key in Popstring
2057 if (active_object
== data
->wd_ActiveObject
)
2059 Object
*current_obj
= active_object
;
2061 D(bug("HandleRawkey: try active object parents handlers\n"));
2062 while (current_obj
!= NULL
)
2064 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2066 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2068 if ((ehn
->ehn_Object
== current_obj
)
2069 && ((ehn
->ehn_Events
& IDCMP_RAWKEY
)
2070 || (ehn
->ehn_Flags
& MUI_EHF_ALWAYSKEYS
)))
2072 //D(bug("HandleRawkey: (active parents) invoking on %p (ehn=%p) "
2073 //"event=%p muikey=%p\n",
2074 //ehn->ehn_Object, ehn, event, muikey));
2075 res
= InvokeEventHandler(ehn
, event
, muikey
);
2076 //D(bug("HandleRawkey: (active parents) got res=%d\n", res));
2077 if (res
& MUI_EventHandlerRC_Eat
)
2080 /* Leave the loop if a different object has been activated */
2081 if (active_object
!= data
->wd_ActiveObject
)
2085 current_obj
= (Object
*)XGET(current_obj
, MUIA_Parent
);
2086 } // while (current_obj != NULL)
2090 } /* if (active_object && !disabled) */
2092 D(bug("HandleRawkey: try default object handlers\n"));
2094 /* try DefaultObject */
2095 if (data
->wd_DefaultObject
!= NULL
)
2096 get(data
->wd_DefaultObject
, MUIA_Disabled
, &disabled
);
2098 if ((data
->wd_DefaultObject
!= NULL
) && !disabled
2099 && (active_object
!= data
->wd_DefaultObject
))
2101 /* No, we only should do this if the object actually has requested this via RequestIDCMP()! */
2102 // if (muikey != MUIKEY_NONE && (_flags(data->wd_DefaultObject) & MADF_CANDRAW))
2104 // DoMethod(data->wd_DefaultObject, MUIM_HandleInput, event, muikey);
2108 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2110 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2112 if ((ehn
->ehn_Object
== data
->wd_DefaultObject
)
2113 && ((ehn
->ehn_Events
& IDCMP_RAWKEY
)
2114 || (ehn
->ehn_Flags
& MUI_EHF_ALWAYSKEYS
)))
2116 //D(bug("HandleRawkey: (default) invoking on %p (ehn=%p) event=%p muikey=%p\n",
2117 //ehn->ehn_Object, ehn, event, muikey));
2118 res
= InvokeEventHandler(ehn
, event
, muikey
);
2119 //D(bug("HandleRawkey: (default) got res=%d\n", res));
2120 if (res
& MUI_EventHandlerRC_Eat
)
2125 } /* if ... default object */
2127 D(bug("HandleRawkey: try other handlers\n"));
2129 // try other handlers
2130 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2132 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2134 // skip Active and Default object as they have already been
2136 if (ehn
->ehn_Object
== data
->wd_ActiveObject
2137 || ehn
->ehn_Object
== data
->wd_DefaultObject
)
2140 if (ehn
->ehn_Events
& IDCMP_RAWKEY
)
2142 //D(bug("HandleRawkey: (others) invoking on %p (ehn=%p) event=%p muikey=%p\n",
2143 //ehn->ehn_Object, ehn, event, muikey));
2144 res
= InvokeEventHandler(ehn
, event
, MUIKEY_NONE
);
2145 //D(bug("HandleRawkey: (others) got res=%d\n", res));
2146 if (res
& MUI_EventHandlerRC_Eat
)
2149 } /* for (mn = data->wd_EHList.mlh_Head; mn->mln_Succ; mn = mn->mln_Succ) */
2151 D(bug("HandleRawkey: try control chars handlers\n"));
2153 /* try Control Chars */
2154 //bug("ctrlchar, key='%c' code=0x%08lx\n", key, event->Code);
2157 for (mn
= data
->wd_CCList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2159 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2161 if (ehn
->ehn_Events
== key
)
2164 LONG muikey2
= ehn
->ehn_Flags
;
2166 get(ehn
->ehn_Object
, MUIA_Disabled
, &disabled
);
2170 //bug("control char\n");
2171 if (event
->Code
& IECODE_UP_PREFIX
)
2173 /* simulate a release */
2174 if (muikey2
== MUIKEY_PRESS
)
2175 muikey2
= MUIKEY_RELEASE
;
2180 if ((muikey2
!= MUIKEY_NONE
)
2181 && (_flags(ehn
->ehn_Object
) & MADF_CANDRAW
)
2182 && (_flags(ehn
->ehn_Object
) & MADF_SHOWME
))
2186 ehn
->ehn_Class
, ehn
->ehn_Object
, MUIM_HandleEvent
,
2189 if (res
& MUI_EventHandlerRC_Eat
)
2194 } /* try control chars */
2197 /* forward non-keystroke events to event handlers */
2198 static void HandleInputEvent(Object
*win
, struct MUI_WindowData
*data
,
2199 struct IntuiMessage
*event
)
2202 struct MUI_EventHandlerNode
*ehn
;
2203 struct IntuiMessage imsg_copy
;
2205 ULONG mask
= event
->Class
;
2207 if (mask
!= IDCMP_IDCMPUPDATE
)
2210 imsg_copy
.IAddress
= NULL
; /* be sure to trap access to that */
2211 ReplyMsg((struct Message
*)event
);
2215 if (mask
== IDCMP_MOUSEMOVE
)
2217 struct Window
*iWin
;
2218 iWin
= event
->IDCMPWindow
;
2220 if (ContextMenuUnderPointer (data
, data
->wd_RootObject
,
2221 event
->MouseX
, event
->MouseY
))
2223 iWin
->Flags
|= WFLG_RMBTRAP
;
2225 else if (!data
->wd_NoMenus
)
2227 iWin
->Flags
&= ~WFLG_RMBTRAP
;
2231 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2233 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2235 if (ehn
->ehn_Events
& mask
)
2239 get(ehn
->ehn_Object
, MUIA_Disabled
, &disabled
);
2243 res
= InvokeEventHandler(ehn
, event
, MUIKEY_NONE
);
2244 if (res
& MUI_EventHandlerRC_Eat
)
2250 if (mask
== IDCMP_IDCMPUPDATE
)
2251 ReplyMsg((struct Message
*)event
);
2255 /* process window message, this does a ReplyMsg() to the message */
2256 /* Called from application.c */
2257 void _zune_window_message(struct IntuiMessage
*imsg
)
2259 struct Window
*iWin
;
2261 struct MUI_WindowData
*data
;
2264 iWin
= imsg
->IDCMPWindow
;
2265 oWin
= (Object
*)iWin
->UserData
;
2266 data
= muiWindowData(oWin
);
2268 if (data
->wd_DragObject
)
2270 HandleDragging(oWin
, data
, imsg
);
2274 handled
= HandleWindowEvent(oWin
, data
, imsg
);
2277 if (IDCMP_RAWKEY
== imsg
->Class
)
2278 HandleRawkey(oWin
, data
, imsg
);
2279 else if (IDCMP_GADGETUP
== imsg
->Class
)
2282 if (ETI_MUI
== ((struct Gadget
*) imsg
->IAddress
)->GadgetID
)
2284 DoMethod(_app(oWin
), MUIM_Application_OpenConfigWindow
);
2290 HandleInputEvent(oWin
, data
, imsg
);
2296 /******************************************************************************/
2297 /******************************************************************************/
2299 /* code for setting MUIA_Window_RootObject */
2300 static void ChangeRootObject (struct MUI_WindowData
*data
, Object
*obj
,
2305 ASSERT_VALID_PTR(data
);
2306 ASSERT_VALID_PTR(obj
);
2308 oldRoot
= data
->wd_RootObject
;
2309 if (!(data
->wd_Flags
& MUIWF_OPENED
))
2313 if (data
->wd_ActiveObject
== oldRoot
)
2314 set(obj
, MUIA_Window_ActiveObject
, MUIV_Window_ActiveObject_None
);
2315 DoMethod(oldRoot
, MUIM_DisconnectParent
);
2318 data
->wd_RootObject
= newRoot
;
2321 /* if window is in App tree, inform child */
2322 if (muiNotifyData(obj
)->mnd_GlobalInfo
)
2323 DoMethod(newRoot
, MUIM_ConnectParent
, (IPTR
)obj
);
2328 // find the ObjNode containing a pointer to the given object
2329 // currently only used for cycle chain objects
2330 static struct ObjNode
*FindObjNode(struct MinList
*list
, Object
*obj
)
2332 struct ObjNode
*node
;
2334 ASSERT_VALID_PTR(list
);
2339 ASSERT_VALID_PTR(obj
);
2341 for (node
= (struct ObjNode
*)list
->mlh_Head
;
2342 node
->node
.mln_Succ
;
2343 node
= (struct ObjNode
*)node
->node
.mln_Succ
)
2345 if (node
->obj
== obj
)
2353 static Object
*GetFirstActiveObject (struct MUI_WindowData
*data
)
2355 ASSERT_VALID_PTR(data
);
2357 if (!IsListEmpty((struct List
*)&data
->wd_CycleChain
))
2358 return ((struct ObjNode
*)data
->wd_CycleChain
.mlh_Head
)->obj
;
2363 static Object
*GetLastActiveObject (struct MUI_WindowData
*data
)
2365 ASSERT_VALID_PTR(data
);
2367 if (!IsListEmpty((struct List
*)&data
->wd_CycleChain
))
2368 return ((struct ObjNode
*)data
->wd_CycleChain
.mlh_TailPred
)->obj
;
2373 typedef struct ObjNode
*objnode_iterator_t(struct ObjNode
*curr_node
);
2375 static objnode_iterator_t NextObjNodeIterator
;
2376 static objnode_iterator_t PrevObjNodeIterator
;
2378 static struct ObjNode
*NextObjNodeIterator (struct ObjNode
*curr_node
)
2380 if (curr_node
->node
.mln_Succ
->mln_Succ
)
2381 return (struct ObjNode
*)curr_node
->node
.mln_Succ
;
2386 static struct ObjNode
*PrevObjNodeIterator (struct ObjNode
*curr_node
)
2388 if (curr_node
->node
.mln_Pred
->mln_Pred
)
2389 return (struct ObjNode
*)curr_node
->node
.mln_Pred
;
2394 static Object
*GetPrevNextActiveObject (struct ObjNode
*old_activenode
, objnode_iterator_t node_iterator
)
2396 struct ObjNode
*curr_node
;
2397 struct ObjNode
*node
;
2400 ASSERT_VALID_PTR(old_activenode
);
2402 curr_node
= old_activenode
;
2408 node
= node_iterator(curr_node
);
2413 /* let's see if this obj meets cycle requirements (enabled & visible) */
2418 get(obj
, MUIA_Disabled
, &is_disabled
);
2420 if (!is_disabled
&& (_flags(obj
) & MADF_SHOWME
))
2434 /**************************************************************************
2435 Code for setting MUIA_Window_ActiveObject
2437 - remove focus drawing for current active object
2438 - find (if needed) the new active object
2439 - set data->wd_ActiveObject to the new object
2440 - draw focus around the new active object
2441 **************************************************************************/
2442 static void SetActiveObject (struct MUI_WindowData
*data
, Object
*obj
, IPTR newval
)
2444 struct ObjNode
*old_activenode
= NULL
;
2446 ASSERT_VALID_PTR(data
);
2447 ASSERT_VALID_PTR(obj
);
2449 D(bug("MUIC_Window:SetActiveObject(data, obj, %08lx) Active=%p\n",
2450 newval
, data
->wd_ActiveObject
));
2452 if ((data
->wd_ActiveObject
!= NULL
)
2453 && (DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
2454 (IPTR
)data
->wd_ActiveObject
) != (IPTR
)NULL
))
2456 if ((IPTR
)data
->wd_ActiveObject
== newval
)
2458 old_activenode
= FindObjNode(&data
->wd_CycleChain
, data
->wd_ActiveObject
);
2459 //if (_flags(data->wd_ActiveObject) & MADF_CANDRAW)
2460 if (data
->wd_Flags
& MUIWF_OBJECTGOACTIVESENT
)
2462 DoMethod(data
->wd_ActiveObject
, MUIM_GoInactive
);
2466 data
->wd_ActiveObject
= NULL
;
2467 data
->wd_Flags
&= ~MUIWF_OBJECTGOACTIVESENT
;
2471 case MUIV_Window_ActiveObject_None
:
2474 case MUIV_Window_ActiveObject_Next
:
2475 if (old_activenode
!= NULL
)
2476 data
->wd_ActiveObject
= GetPrevNextActiveObject(old_activenode
,
2477 NextObjNodeIterator
);
2478 if (NULL
== data
->wd_ActiveObject
)
2479 data
->wd_ActiveObject
= GetFirstActiveObject(data
);
2482 case MUIV_Window_ActiveObject_Prev
:
2484 data
->wd_ActiveObject
= GetPrevNextActiveObject(old_activenode
,
2485 PrevObjNodeIterator
);
2486 if (NULL
== data
->wd_ActiveObject
)
2487 data
->wd_ActiveObject
= GetLastActiveObject(data
);
2491 data
->wd_ActiveObject
= (Object
*)newval
;
2495 if (data
->wd_ActiveObject
!= NULL
2496 && DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
2497 (IPTR
)data
->wd_ActiveObject
)
2498 && (_flags(data
->wd_ActiveObject
) & MADF_CANDRAW
))
2500 DoMethod(data
->wd_ActiveObject
, MUIM_GoActive
);
2501 data
->wd_Flags
|= MUIWF_OBJECTGOACTIVESENT
;
2507 * calculate real dimensions from programmer requirements.
2508 * may be overridden by user settings if MUIA_Window_ID is set.
2510 /* MUIV_Window_Height_Screen and MUIV_Window_Height_Visible
2511 * are not handled yet, as their Width couterparts.
2513 static void WindowSelectDimensions (struct MUI_WindowData
*data
)
2515 if (!data
->wd_Width
)
2517 if (data
->wd_ReqWidth
> 0) data
->wd_Width
= data
->wd_ReqWidth
;
2518 else if (data
->wd_ReqWidth
== MUIV_Window_Width_Default
)
2519 data
->wd_Width
= data
->wd_MinMax
.DefWidth
;
2520 else if (_between(MUIV_Window_Width_MinMax(100),
2522 MUIV_Window_Width_MinMax(0)))
2524 data
->wd_Width
= data
->wd_MinMax
.MinWidth
2526 * (data
->wd_MinMax
.MaxWidth
- data
->wd_MinMax
.MinWidth
);
2528 else if (_between(MUIV_Window_Width_Screen(100),
2530 MUIV_Window_Width_Screen(0)))
2532 data
->wd_Width
= data
->wd_RenderInfo
.mri_ScreenWidth
2533 * (- (data
->wd_ReqWidth
+ 200)) / 100;
2535 else if (_between(MUIV_Window_Width_Visible(100),
2537 MUIV_Window_Width_Visible(0)))
2539 data
->wd_Width
= data
->wd_RenderInfo
.mri_ScreenWidth
2540 * (- (data
->wd_ReqWidth
+ 100)) / 100;
2543 if (data
->wd_ReqHeight
> 0) data
->wd_Height
= data
->wd_ReqHeight
;
2544 else if (data
->wd_ReqHeight
== MUIV_Window_Height_Default
)
2545 data
->wd_Height
= data
->wd_MinMax
.DefHeight
;
2546 else if (_between(MUIV_Window_Height_MinMax(100),
2548 MUIV_Window_Height_MinMax(0)))
2550 data
->wd_Height
= data
->wd_MinMax
.MinHeight
2551 - data
->wd_ReqHeight
2552 * (data
->wd_MinMax
.MaxHeight
- data
->wd_MinMax
.MinHeight
);
2554 else if (_between(MUIV_Window_Height_Screen(100),
2556 MUIV_Window_Height_Screen(0)))
2561 scr
= data
->wd_RenderInfo
.mri_Screen
;
2563 height
= scr
->Height
- data
->wd_RenderInfo
.mri_BorderTop
- data
->wd_RenderInfo
.mri_BorderBottom
;
2565 /* This is new to Zune: If TopEdge Delta is requested
2566 * the screenheight doesn't cover the barlayer */
2567 if (data
->wd_Y
<= MUIV_Window_TopEdge_Delta(0))
2568 height
-= scr
->BarHeight
+ 1;
2570 data
->wd_Height
= height
* (- (data
->wd_ReqHeight
+ 200)) / 100;
2572 else if (_between(MUIV_Window_Height_Visible(100),
2574 MUIV_Window_Height_Visible(0)))
2576 data
->wd_Height
= data
->wd_RenderInfo
.mri_ScreenHeight
2577 * (- (data
->wd_ReqHeight
+ 100)) / 100;
2581 if (data
->wd_ReqWidth
== MUIV_Window_Width_Scaled
)
2582 data
->wd_Width
= data
->wd_Height
* data
->wd_MinMax
.MinWidth
2583 / data
->wd_MinMax
.MinHeight
;
2584 else if (data
->wd_ReqHeight
== MUIV_Window_Width_Scaled
)
2585 data
->wd_Height
= data
->wd_Width
* data
->wd_MinMax
.MinHeight
2586 / data
->wd_MinMax
.MinWidth
;
2588 data
->wd_Width
= CLAMP(data
->wd_Width
, data
->wd_MinMax
.MinWidth
,
2589 data
->wd_MinMax
.MaxWidth
);
2590 data
->wd_Height
= CLAMP(data
->wd_Height
, data
->wd_MinMax
.MinHeight
,
2591 data
->wd_MinMax
.MaxHeight
);
2595 /**************************************************************************
2597 **************************************************************************/
2598 IPTR
Window__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
2600 struct MUI_WindowData
*data
;
2601 const struct TagItem
*tags
;
2602 struct TagItem
*tag
;
2604 obj
= (Object
*)DoSuperMethodA(cl
, obj
, (Msg
)msg
);
2608 /* Initial local instance data */
2609 data
= INST_DATA(cl
, obj
);
2611 data
->wd_MemoryPool
= CreatePool(0, 4096, 2048);
2612 if (NULL
== data
->wd_MemoryPool
)
2614 CoerceMethod(cl
, obj
, OM_DISPOSE
);
2618 data
->wd_RenderInfo
.mri_WindowObject
= obj
;
2620 NewList((struct List
*)&(data
->wd_EHList
));
2621 NewList((struct List
*)&(data
->wd_CCList
));
2622 NewList((struct List
*)&(data
->wd_CycleChain
));
2623 NewList((struct List
*)&(data
->wd_IDList
));
2625 data
->wd_CrtFlags
= WFLG_SIZEGADGET
| WFLG_DRAGBAR
| WFLG_DEPTHGADGET
2626 | WFLG_CLOSEGADGET
| WFLG_SIMPLE_REFRESH
2627 | WFLG_REPORTMOUSE
| WFLG_NEWLOOKMENUS
;
2628 data
->wd_ZoomGadget
= TRUE
;
2629 data
->wd_Events
= GetDefaultEvents();
2630 data
->wd_ActiveObject
= NULL
;
2632 data
->wd_ReqHeight
= MUIV_Window_Height_Default
;
2633 data
->wd_ReqWidth
= MUIV_Window_Width_Default
;
2634 data
->wd_RootObject
= NULL
;
2635 data
->wd_DefaultObject
= NULL
;
2637 /* alternate dimensions */
2638 /* no change in coordinates */
2639 data
->wd_AltDim
.Top
= MUIV_Window_AltTopEdge_NoChange
;
2640 data
->wd_AltDim
.Left
= MUIV_Window_AltLeftEdge_NoChange
;
2641 /* default to min size */
2642 data
->wd_AltDim
.Width
= MUIV_Window_AltWidth_MinMax(0);
2643 data
->wd_AltDim
.Height
= MUIV_Window_AltHeight_MinMax(0);
2644 data
->wd_X
= MUIV_Window_LeftEdge_Centered
;
2645 data
->wd_Y
= MUIV_Window_TopEdge_Centered
;
2646 data
->wd_DisabledKeys
= 0L;
2647 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_FIRST
;
2649 /* parse initial taglist */
2651 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
)); )
2653 switch (tag
->ti_Tag
)
2655 case MUIA_Window_EraseArea
:
2656 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_ERASEAREA
);
2659 case MUIA_Window_ToolBox
:
2660 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_TOOLBOX
);
2663 case MUIA_Window_CloseGadget
:
2664 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_CLOSEGADGET
);
2667 case MUIA_Window_SizeGadget
:
2668 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_SIZEGADGET
);
2671 case MUIA_Window_ZoomGadget
:
2672 data
->wd_ZoomGadget
= tag
->ti_Data
;
2675 case MUIA_Window_Backdrop
:
2676 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_BACKDROP
);
2679 case MUIA_Window_Borderless
:
2680 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_BORDERLESS
);
2683 case MUIA_Window_DepthGadget
:
2684 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_DEPTHGADGET
);
2687 case MUIA_Window_DragBar
:
2688 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_DRAGBAR
);
2691 case MUIA_Window_SizeRight
:
2692 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_SIZEBRIGHT
);
2695 case MUIA_Window_Height
:
2696 data
->wd_ReqHeight
= (LONG
)tag
->ti_Data
;
2699 case MUIA_Window_Width
:
2700 data
->wd_ReqWidth
= (LONG
)tag
->ti_Data
;
2703 case MUIA_Window_ID
:
2704 set(obj
, MUIA_Window_ID
, tag
->ti_Data
);
2707 case MUIA_Window_IsSubWindow
:
2708 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_ISSUBWINDOW
);
2711 case MUIA_Window_Title
:
2712 set(obj
, MUIA_Window_Title
, tag
->ti_Data
);
2715 case MUIA_Window_ScreenTitle
:
2716 set(obj
, MUIA_Window_ScreenTitle
, tag
->ti_Data
);
2719 case MUIA_Window_Activate
:
2720 _handle_bool_tag(data
->wd_Flags
, !tag
->ti_Data
, MUIWF_DONTACTIVATE
);
2723 case MUIA_Window_DefaultObject
:
2724 set(obj
, MUIA_Window_DefaultObject
, tag
->ti_Data
);
2727 case MUIA_Window_Menustrip
:
2728 data
->wd_ChildMenustrip
= (Object
*)tag
->ti_Data
;
2731 case MUIA_Window_NoMenus
:
2732 data
->wd_NoMenus
= (BOOL
) tag
->ti_Data
;
2735 case MUIA_Window_RootObject
:
2738 CoerceMethod(cl
, obj
, OM_DISPOSE
);
2741 set(obj
, MUIA_Window_RootObject
, tag
->ti_Data
);
2744 case MUIA_Window_AltHeight
:
2745 data
->wd_AltDim
.Height
= (WORD
)tag
->ti_Data
;
2748 case MUIA_Window_AltWidth
:
2749 data
->wd_AltDim
.Width
= (WORD
)tag
->ti_Data
;
2752 case MUIA_Window_AltLeftEdge
:
2753 data
->wd_AltDim
.Left
= (WORD
)tag
->ti_Data
;
2756 case MUIA_Window_AltTopEdge
:
2757 data
->wd_AltDim
.Top
= (WORD
)tag
->ti_Data
;
2760 case MUIA_Window_AppWindow
:
2761 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_ISAPPWINDOW
);
2764 case MUIA_Window_LeftEdge
:
2765 data
->wd_X
= tag
->ti_Data
;
2768 case MUIA_Window_TopEdge
:
2769 data
->wd_Y
= tag
->ti_Data
;
2772 case MUIA_Window_UseBottomBorderScroller
:
2773 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_USEBOTTOMSCROLLER
);
2776 case MUIA_Window_UseRightBorderScroller
:
2777 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_USERIGHTSCROLLER
);
2780 case MUIA_Window_DisableKeys
:
2781 data
->wd_DisabledKeys
= tag
->ti_Data
;
2784 case MUIA_Window_RefWindow
:
2785 data
->wd_RefWindow
= (Object
*)tag
->ti_Data
;
2788 case MUIA_Window_Screen
:
2789 data
->wd_UserScreen
= (struct Screen
*)tag
->ti_Data
;
2792 case MUIA_Window_PublicScreen
:
2793 data
->wd_UserPublicScreen
= (STRPTR
)tag
->ti_Data
;
2798 /* D(bug("muimaster.library/window.c: Window Object created at 0x%lx back=%lx\n", */
2799 /* obj,data->wd_Background)); */
2804 /**************************************************************************
2806 **************************************************************************/
2807 IPTR
Window__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
2809 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
2811 /* D(bug("Window_Dispose(%p)\n", obj)); */
2813 #if 0 /* We no longer clear muiGlobalInfo() during disconnections, so
2814 this can cause problems (remove object which is already removed).
2815 Furthermore AFAIK it is not legal to dispose a window object
2816 which is still ocnnected to the application object, anyway. */
2818 if (muiGlobalInfo(obj
) && _app(obj
))
2820 /* D(bug(" Window_Dispose(%p) : calling app->OM_REMMEMBER\n", obj)); */
2821 DoMethod(_app(obj
), OM_REMMEMBER
, (IPTR
)obj
);
2825 if (data
->wd_RootObject
)
2826 MUI_DisposeObject(data
->wd_RootObject
);
2828 if (data
->wd_ChildMenustrip
)
2829 MUI_DisposeObject(data
->wd_ChildMenustrip
);
2831 if (data
->wd_Title
) FreeVec(data
->wd_Title
);
2832 if (data
->wd_ScreenTitle
)FreeVec(data
->wd_ScreenTitle
);
2834 DeletePool(data
->wd_MemoryPool
);
2836 /* D(bug(" Window_Dispose(%p) : calling supermethod\n", obj)); */
2837 return DoSuperMethodA(cl
, obj
, msg
);
2840 static ULONG
WindowOpen(struct IClass
*cl
, Object
*obj
);
2841 static ULONG
WindowClose(struct IClass
*cl
, Object
*obj
);
2843 /**************************************************************************
2845 **************************************************************************/
2846 IPTR
Window__OM_SET(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
2848 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
2849 const struct TagItem
*tags
= msg
->ops_AttrList
;
2850 const struct TagItem
*tag
;
2852 while ((tag
= NextTagItem(&tags
)) != NULL
)
2854 switch (tag
->ti_Tag
)
2856 case MUIA_Window_Activate
:
2857 if (data
->wd_RenderInfo
.mri_Window
)
2859 if (tag
->ti_Data
&& !(data
->wd_Flags
& MUIWF_ACTIVE
))
2861 ActivateWindow(data
->wd_RenderInfo
.mri_Window
);
2862 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_ACTIVE
);
2866 _handle_bool_tag(data
->wd_Flags
, !tag
->ti_Data
, MUIWF_DONTACTIVATE
);
2869 case MUIA_Window_ActiveObject
:
2870 /* D(bug("MUIA_Window_ActiveObject %ld (%p)\n", tag->ti_Data, tag->ti_Data)); */
2871 SetActiveObject(data
, obj
, tag
->ti_Data
);
2874 case MUIA_Window_DefaultObject
:
2875 data
->wd_DefaultObject
= (APTR
)tag
->ti_Data
;
2878 case MUIA_Window_ID
:
2879 data
->wd_ID
= tag
->ti_Data
;
2882 case MUIA_Window_IsSubWindow
:
2883 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_ISSUBWINDOW
);
2886 case MUIA_Window_Open
:
2889 if (data
->wd_Flags
& MUIWF_HIDDEN
)
2890 data
->wd_Flags
|= MUIWF_OPENONUNHIDE
;
2892 if (!(data
->wd_Flags
& MUIWF_OPENED
))
2893 WindowOpen(cl
, obj
);
2896 DoMethod(obj
, MUIM_Window_ToFront
);
2897 set(obj
, MUIA_Window_Activate
, TRUE
);
2901 if (data
->wd_Flags
& MUIWF_HIDDEN
)
2902 data
->wd_Flags
&= ~MUIWF_OPENONUNHIDE
;
2904 if (data
->wd_Flags
& MUIWF_OPENED
)
2905 WindowClose(cl
, obj
);
2908 case MUIA_ShowMe
: /* PRIVATE *abuse* of the Area's ShowMe attr */
2913 if (data
->wd_Flags
& MUIWF_HIDDEN
)
2915 data
->wd_Flags
&= ~MUIWF_HIDDEN
;
2917 if (data
->wd_Flags
& MUIWF_OPENONUNHIDE
)
2919 data
->wd_Flags
&= ~MUIWF_OPENONUNHIDE
;
2920 set(obj
, MUIA_Window_Open
, TRUE
);
2928 if (data
->wd_Flags
& MUIWF_OPENED
)
2930 data
->wd_Flags
|= MUIWF_OPENONUNHIDE
;
2932 set(obj
, MUIA_Window_Open
, FALSE
);
2935 data
->wd_Flags
|= MUIWF_HIDDEN
;
2939 case MUIA_Window_RootObject
:
2940 ChangeRootObject(data
, obj
, (Object
*)tag
->ti_Data
);
2943 case MUIA_Window_Title
:
2944 if (data
->wd_Title
) FreeVec(data
->wd_Title
);
2945 data
->wd_Title
= StrDup((STRPTR
)tag
->ti_Data
);
2946 if (data
->wd_RenderInfo
.mri_Window
)
2947 SetWindowTitles(data
->wd_RenderInfo
.mri_Window
,data
->wd_Title
, (CONST_STRPTR
)~0);
2950 case MUIA_Window_ScreenTitle
:
2951 if (data
->wd_ScreenTitle
) FreeVec(data
->wd_ScreenTitle
);
2952 data
->wd_ScreenTitle
= StrDup((STRPTR
)tag
->ti_Data
);
2953 if (data
->wd_RenderInfo
.mri_Window
)
2954 SetWindowTitles(data
->wd_RenderInfo
.mri_Window
,
2955 (CONST_STRPTR
)~0, data
->wd_ScreenTitle
);
2958 case MUIA_Window_NoMenus
:
2959 data
->wd_NoMenus
= (BOOL
) tag
->ti_Data
;
2960 if (data
->wd_RenderInfo
.mri_Window
)
2962 if (data
->wd_NoMenus
)
2963 data
->wd_RenderInfo
.mri_Window
->Flags
|= WFLG_RMBTRAP
;
2965 data
->wd_RenderInfo
.mri_Window
->Flags
&= ~WFLG_RMBTRAP
;
2970 case MUIA_Window_UseBottomBorderScroller
:
2971 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_USEBOTTOMSCROLLER
);
2974 case MUIA_Window_UseRightBorderScroller
:
2975 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_USERIGHTSCROLLER
);
2978 case MUIA_Window_DisableKeys
:
2979 data
->wd_DisabledKeys
= tag
->ti_Data
;
2982 case MUIA_Window_RefWindow
:
2983 data
->wd_RefWindow
= (Object
*)tag
->ti_Data
;
2986 #warning "TODO: obsolete hacked atribute - remove"
2987 #if defined(MUIA_Window_WandererBackdrop)
2988 case MUIA_Window_WandererBackdrop
:
2989 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_BACKDROP
);
2990 _handle_bool_tag(data
->wd_CrtFlags
, !tag
->ti_Data
, WFLG_DRAGBAR
);
2991 _handle_bool_tag(data
->wd_CrtFlags
, !tag
->ti_Data
, WFLG_SIZEGADGET
);
2992 _handle_bool_tag(data
->wd_CrtFlags
, !tag
->ti_Data
, WFLG_CLOSEGADGET
);
2993 _handle_bool_tag(data
->wd_CrtFlags
, !tag
->ti_Data
, WFLG_DEPTHGADGET
);
2994 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_BORDERLESS
);
2997 data
->wd_ReqWidth
= (LONG
)MUIV_Window_Width_Screen(100);
2998 /* won't take the barlayer into account */
2999 data
->wd_ReqHeight
= (LONG
)MUIV_Window_Height_Screen(100);
3001 data
->wd_Height
= 0;
3002 data
->wd_X
= (LONG
)0;
3003 /* place the window below the bar layer */
3004 data
->wd_Y
= (LONG
)MUIV_Window_TopEdge_Delta(0);
3009 case MUIA_Window_LeftEdge
:
3010 data
->wd_X
= tag
->ti_Data
;
3013 case MUIA_Window_TopEdge
:
3014 data
->wd_Y
= tag
->ti_Data
;
3017 case MUIA_Window_Width
:
3018 data
->wd_ReqWidth
= (LONG
)tag
->ti_Data
;
3019 data
->wd_Width
= 0; /* otherwise windowselectdimensions() ignores ReqWidth */
3022 case MUIA_Window_Height
:
3023 data
->wd_ReqHeight
= (LONG
)tag
->ti_Data
;
3024 data
->wd_Height
= 0;
3027 case MUIA_Window_Screen
:
3028 data
->wd_UserScreen
= (struct Screen
*)tag
->ti_Data
;
3031 case MUIA_Window_PublicScreen
:
3032 data
->wd_UserPublicScreen
= (STRPTR
)tag
->ti_Data
;
3039 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
3042 /**************************************************************************
3044 **************************************************************************/
3045 IPTR
Window__OM_GET(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
3047 #define STORE *(msg->opg_Storage)
3049 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3053 switch(msg
->opg_AttrID
)
3055 case MUIA_Window_Activate
:
3056 STORE
= (data
->wd_Flags
& (MUIWF_ACTIVE
| MUIWF_OPENED
)) == (MUIWF_ACTIVE
| MUIWF_OPENED
);
3059 case MUIA_Window_Window
:
3060 STORE
= (IPTR
)data
->wd_RenderInfo
.mri_Window
;
3063 case MUIA_Window_Screen
:
3064 STORE
= (IPTR
)data
->wd_RenderInfo
.mri_Screen
;
3067 case MUIA_Window_PublicScreen
:
3068 STORE
= (IPTR
)data
->wd_UserPublicScreen
;
3071 case MUIA_Window_ActiveObject
:
3072 if ((data
->wd_ActiveObject
!= NULL
)
3073 && (DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
3074 (IPTR
)data
->wd_ActiveObject
) != (IPTR
)NULL
))
3075 STORE
= (IPTR
)data
->wd_ActiveObject
;
3080 case MUIA_Window_CloseRequest
:
3084 case MUIA_Window_DefaultObject
:
3085 STORE
= (IPTR
)data
->wd_DefaultObject
;
3088 case MUIA_Window_DisableKeys
:
3089 STORE
= data
->wd_DisabledKeys
;
3092 case MUIA_Window_Height
:
3093 STORE
= (IPTR
)data
->wd_Height
;
3096 case MUIA_Window_ID
:
3097 STORE
= data
->wd_ID
;
3100 case MUIA_Window_IsSubWindow
:
3101 STORE
= (data
->wd_Flags
& MUIWF_ISSUBWINDOW
) == MUIWF_ISSUBWINDOW
;
3104 case MUIA_Window_LeftEdge
:
3105 if (data
->wd_RenderInfo
.mri_Window
)
3106 STORE
= (IPTR
)data
->wd_RenderInfo
.mri_Window
->LeftEdge
;
3111 case MUIA_Window_Open
:
3112 STORE
= (data
->wd_Flags
& MUIWF_OPENED
) == MUIWF_OPENED
;
3115 case MUIA_Window_RootObject
:
3116 STORE
= (IPTR
)data
->wd_RootObject
;
3119 case MUIA_Window_ScreenTitle
:
3120 STORE
= (IPTR
)data
->wd_ScreenTitle
;
3123 case MUIA_Window_Title
:
3124 STORE
= (IPTR
)data
->wd_Title
;
3127 case MUIA_Window_TopEdge
:
3128 if (data
->wd_RenderInfo
.mri_Window
)
3129 STORE
= (IPTR
)data
->wd_RenderInfo
.mri_Window
->TopEdge
;
3134 case MUIA_Window_Width
:
3135 STORE
= (IPTR
)data
->wd_Width
;
3138 case MUIA_Window_Menustrip
:
3139 STORE
= (IPTR
)data
->wd_ChildMenustrip
;
3151 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
3156 * MUIM_FindUData : tests if the MUIA_UserData of the object
3157 * contains the given <udata> and returns the object pointer in this case.
3159 IPTR
Window__MUIM_FindUData(struct IClass
*cl
, Object
*obj
, struct MUIP_FindUData
*msg
)
3161 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3163 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3166 if (data
->wd_RootObject
)
3167 return DoMethodA(data
->wd_RootObject
, (Msg
)msg
);
3174 * MUIM_GetUData : This method tests if the MUIA_UserData of the object
3175 * contains the given <udata> and gets <attr> to <storage> for itself
3178 IPTR
Window__MUIM_GetUData(struct IClass
*cl
, Object
*obj
, struct MUIP_GetUData
*msg
)
3180 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3182 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3184 get(obj
, msg
->attr
, msg
->storage
);
3188 if (data
->wd_RootObject
)
3189 return DoMethodA(data
->wd_RootObject
, (Msg
)msg
);
3196 * MUIM_SetUData : This method tests if the MUIA_UserData of the object
3197 * contains the given <udata> and sets <attr> to <val> for itself in this case.
3199 IPTR
Window__MUIM_SetUData(struct IClass
*cl
, Object
*obj
, struct MUIP_SetUData
*msg
)
3201 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3203 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3204 set(obj
, msg
->attr
, msg
->val
);
3206 if (data
->wd_RootObject
)
3207 DoMethodA(data
->wd_RootObject
, (Msg
)msg
);
3214 * MUIM_SetUDataOnce : This method tests if the MUIA_UserData of the object
3215 * contains the given <udata> and sets <attr> to <val> for itself in this case.
3217 IPTR
Window__MUIM_SetUDataOnce(struct IClass
*cl
, Object
*obj
, struct MUIP_SetUDataOnce
*msg
)
3219 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3221 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3223 set(obj
, msg
->attr
, msg
->val
);
3227 if (data
->wd_RootObject
)
3228 return DoMethodA(data
->wd_RootObject
, (Msg
)msg
);
3233 /**************************************************************************
3234 Called by Application (parent) object whenever this object is added.
3236 **************************************************************************/
3237 IPTR
Window__MUIM_ConnectParent(struct IClass
*cl
, Object
*obj
,
3238 struct MUIP_ConnectParent
*msg
)
3240 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3242 if (!DoSuperMethodA(cl
,obj
,(Msg
)msg
)) return 0;
3244 if (data
->wd_RootObject
)
3245 DoMethod(data
->wd_RootObject
, MUIM_ConnectParent
, (IPTR
)obj
);
3247 if (data
->wd_ChildMenustrip
)
3248 DoMethod(data
->wd_ChildMenustrip
, MUIM_ConnectParent
, (IPTR
)obj
);
3254 /**************************************************************************
3255 called by parent object
3256 **************************************************************************/
3257 IPTR
Window__MUIM_DisconnectParent(struct IClass
*cl
, Object
*obj
, struct MUIP_DisconnectParent
*msg
)
3259 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3261 /* D(bug("Window_DisconnectParent(%p) : muiGlobalInfo=%p\n", muiGlobalInfo(obj))); */
3262 if (muiGlobalInfo(obj
))
3264 /* Close the window before disconnecting all the childs */
3265 if ((data
->wd_Flags
& MUIWF_OPENED
))
3267 /* D(bug(" Window_DisconnectParent(%p) : closing window\n", muiGlobalInfo(obj))); */
3268 set(obj
, MUIA_Window_Open
, FALSE
);
3270 if (data
->wd_ChildMenustrip
)
3271 DoMethod(data
->wd_ChildMenustrip
, MUIM_DisconnectParent
, (IPTR
)obj
);
3273 if (data
->wd_RootObject
)
3274 DoMethodA(data
->wd_RootObject
, (Msg
)msg
);
3276 /* D(bug(" Window_DisconnectParent(%p) : calling supermethod\n", muiGlobalInfo(obj))); */
3277 return DoSuperMethodA(cl
,obj
,(Msg
)msg
);
3285 static void SetRootObjInnerSpacing(Object
*obj
, struct MUI_WindowData
*data
)
3287 UWORD wd_innerLeft
, wd_innerRight
, wd_innerTop
, wd_innerBottom
;
3289 if (data
->wd_CrtFlags
& WFLG_BORDERLESS
)
3298 wd_innerLeft
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_left
;
3299 wd_innerRight
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_right
;
3300 wd_innerTop
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_top
;
3301 wd_innerBottom
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_bottom
;
3304 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERLEFT
))
3306 muiAreaData(data
->wd_RootObject
)->mad_InnerLeft
= wd_innerLeft
;
3309 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERTOP
))
3311 muiAreaData(data
->wd_RootObject
)->mad_InnerTop
= wd_innerTop
;
3314 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERRIGHT
))
3316 muiAreaData(data
->wd_RootObject
)->mad_InnerRight
= wd_innerRight
;
3319 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERBOTTOM
))
3321 muiAreaData(data
->wd_RootObject
)->mad_InnerBottom
= wd_innerBottom
;
3326 * Called before window is opened or resized. It determines its bounds,
3327 * so you can call WindowSelectDimensions() to find the final dims.
3329 static void WindowMinMax(Object
*obj
, struct MUI_WindowData
*data
)
3331 SetRootObjInnerSpacing(obj
, data
);
3332 /* inquire about sizes */
3333 DoMethod(data
->wd_RootObject
, MUIM_AskMinMax
, (IPTR
)&data
->wd_MinMax
);
3334 /* D(bug("*** root minmax = %ld,%ld => %ld,%ld\n", data->wd_MinMax.MinWidth, */
3335 /* data->wd_MinMax.MinHeight, */
3336 /* data->wd_MinMax.MaxWidth, data->wd_MinMax.MaxHeight)); */
3337 __area_finish_minmax(data
->wd_RootObject
, &data
->wd_MinMax
);
3338 /* D(bug("*** root minmax2 = %ld,%ld => %ld,%ld\n", data->wd_MinMax.MinWidth, */
3339 /* data->wd_MinMax.MinHeight, */
3340 /* data->wd_MinMax.MaxWidth, data->wd_MinMax.MaxHeight)); */
3344 static void InstallBackbuffer (struct IClass
*cl
, Object
*obj
)
3346 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3348 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
3350 data
->wd_RenderInfo
.mri_BufferBM
=
3351 AllocBitMap(win
->Width
, win
->Height
, win
->RPort
->BitMap
->Depth
,
3352 0, win
->RPort
->BitMap
);
3354 if (data
->wd_RenderInfo
.mri_BufferBM
)
3356 /* D(bug("install_backbuffer : allocated bitmap %dx%dx%d with friend %p\n", */
3357 /* win->Width, win->Height, win->RPort->BitMap->Depth, win->RPort->BitMap)); */
3358 InitRastPort(&data
->wd_RenderInfo
.mri_BufferRP
);
3359 data
->wd_RenderInfo
.mri_BufferRP
.BitMap
= data
->wd_RenderInfo
.mri_BufferBM
;
3363 static void DeinstallBackbuffer (struct IClass
*cl
, Object
*obj
)
3365 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3367 if (data
->wd_RenderInfo
.mri_BufferBM
)
3369 DeinitRastPort(&data
->wd_RenderInfo
.mri_BufferRP
);
3370 FreeBitMap(data
->wd_RenderInfo
.mri_BufferBM
);
3371 data
->wd_RenderInfo
.mri_BufferBM
= NULL
;
3376 * Called after window is opened or resized.
3377 * An expose event is already queued, it will trigger
3378 * MUIM_Draw for us when going back to main loop.
3380 static void WindowShow (struct IClass
*cl
, Object
*obj
)
3382 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3383 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
3384 /* D(bug("window_show %s %d\n", __FILE__, __LINE__)); */
3386 _left(data
->wd_RootObject
) = win
->BorderLeft
;
3387 _top(data
->wd_RootObject
) = win
->BorderTop
;
3388 _width(data
->wd_RootObject
) = data
->wd_Width
;
3389 _height(data
->wd_RootObject
) = data
->wd_Height
;
3391 DoMethod(data
->wd_RootObject
, MUIM_Layout
);
3393 ShowRenderInfo(&data
->wd_RenderInfo
);
3394 /* D(bug("zune_imspec_show %s %d\n", __FILE__, __LINE__)); */
3395 zune_imspec_show(data
->wd_Background
, obj
);
3396 DoShowMethod(data
->wd_RootObject
);
3399 static ULONG
WindowOpen(struct IClass
*cl
, Object
*obj
)
3401 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3403 if (!data
->wd_RootObject
)
3406 if (!DoMethod(obj
, MUIM_Window_Setup
))
3409 /* I got display info, so calculate your display dependant data */
3410 if (!DoSetupMethod(data
->wd_RootObject
, &data
->wd_RenderInfo
))
3412 DoMethod(obj
, MUIM_Window_Cleanup
);
3416 /* inquire about sizes */
3417 WindowMinMax(obj
,data
);
3418 WindowSelectDimensions(data
);
3420 /* Decide which menustrip should be used */
3421 if (!data
->wd_ChildMenustrip
)
3422 get(_app(obj
), MUIA_Application_Menustrip
, &data
->wd_Menustrip
);
3424 data
->wd_Menustrip
= data
->wd_ChildMenustrip
;
3426 /* open window here ... */
3427 if (!DisplayWindow(obj
,data
))
3429 /* free display dependant data */
3430 data
->wd_Menustrip
= NULL
;
3431 DoMethod(data
->wd_RootObject
, MUIM_Cleanup
);
3432 DoMethod(obj
, MUIM_Window_Cleanup
);
3436 InstallBackbuffer(cl
, obj
);
3438 data
->wd_Flags
|= MUIWF_OPENED
;
3440 WindowShow(cl
, obj
);
3443 LONG left
,top
,width
,height
;
3445 left
= data
->wd_RenderInfo
.mri_Window
->BorderLeft
;
3446 top
= data
->wd_RenderInfo
.mri_Window
->BorderTop
,
3447 width
= data
->wd_RenderInfo
.mri_Window
->Width
3448 - data
->wd_RenderInfo
.mri_Window
->BorderRight
- left
;
3449 height
= data
->wd_RenderInfo
.mri_Window
->Height
3450 - data
->wd_RenderInfo
.mri_Window
->BorderBottom
- top
;
3452 /* D(bug("zune_imspec_draw %s %d\n", __FILE__, __LINE__)); */
3453 // D(bug("%d:zune_imspec_draw(%p) l=%d t=%d w=%d h=%d xo=%d yo=%d\n",
3454 // __LINE__, data->wd_Background, left, top, width,
3455 // height, left, top));
3457 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
3458 left
, top
, width
, height
, left
, top
, 0);
3461 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWOBJECT
);
3463 D(bug("MUIC_Window:windowOpen() ActiveObject=%p\n", data
->wd_ActiveObject
));
3464 if (data
->wd_OldActive
!= NULL
)
3466 set(obj
, MUIA_Window_ActiveObject
, data
->wd_OldActive
);
3472 /******************************************************************************/
3473 /******************************************************************************/
3475 static ULONG
WindowClose(struct IClass
*cl
, Object
*obj
)
3477 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3479 if (data
->wd_ActiveObject
!= NULL
)
3481 data
->wd_OldActive
= data
->wd_ActiveObject
;
3482 set(obj
, MUIA_Window_ActiveObject
, MUIV_Window_ActiveObject_None
);
3485 KillHelpBubble(data
, obj
, BUBBLEHELP_TICKER_FIRST
);
3487 /* remove from window */
3488 DoHideMethod(data
->wd_RootObject
);
3489 zune_imspec_hide(data
->wd_Background
);
3491 DeinstallBackbuffer(cl
, obj
);
3493 HideRenderInfo(&data
->wd_RenderInfo
);
3495 /* close here ... */
3496 UndisplayWindow(obj
,data
);
3498 data
->wd_Flags
&= ~MUIWF_OPENED
;
3499 data
->wd_Menustrip
= NULL
;
3501 /* free display dependant data */
3502 DoMethod(data
->wd_RootObject
, MUIM_Cleanup
);
3503 DoMethod(obj
, MUIM_Window_Cleanup
);
3507 /* calculate a new layout
3509 * see Group_ExitChange
3513 IPTR
Window__MUIM_RecalcDisplay(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_RecalcDisplay
*msg
)
3515 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3516 LONG left
,top
,width
,height
;
3518 Object
*current_obj
;
3520 if (!(data
->wd_Flags
& MUIWF_OPENED
))
3523 current_obj
= msg
->originator
;
3525 // typically originator is a group which has been added/removed a child
3526 // calculate minmax of current obj
3527 // if new minmax can accomodate current obj size, stop
3528 // else try with its parent
3529 // the resulting object will get a new layout
3530 // it currently produces some redundant AskMinMax but allows
3531 // to not always relayout the whole window
3533 D(bug("RecalcDisplay on %p\n", current_obj
));
3534 while (current_obj
!= NULL
)
3536 DoMethod(current_obj
, MUIM_AskMinMax
, (IPTR
)&muiAreaData(current_obj
)->mad_MinMax
);
3537 __area_finish_minmax(current_obj
, &muiAreaData(current_obj
)->mad_MinMax
);
3539 D(bug("size w = %d, h = %d\n", _width(current_obj
), _height(current_obj
)));
3540 D(bug("new w = %d-%d, h = %d-%d\n", _minwidth(current_obj
), _maxwidth(current_obj
),
3541 _minheight(current_obj
), _maxheight(current_obj
)));
3543 if (!_between(_minwidth(current_obj
), _width(current_obj
), _maxwidth(current_obj
))
3544 || !_between(_minheight(current_obj
), _height(current_obj
), _maxheight(current_obj
)))
3546 current_obj
= _parent(current_obj
);
3547 D(bug("RecalcDisplay, try parent %p\n", current_obj
));
3551 D(bug("found it\n"));
3557 current_obj
= data
->wd_RootObject
;
3559 WindowMinMax(obj
, data
);
3560 DoHideMethod(current_obj
);
3561 /* resize window ? */
3562 WindowSelectDimensions(data
);
3563 resized
= WindowResize(data
);
3566 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
3567 _left(data
->wd_RootObject
) = win
->BorderLeft
;
3568 _top(data
->wd_RootObject
) = win
->BorderTop
;
3569 _width(data
->wd_RootObject
) = data
->wd_Width
;
3570 _height(data
->wd_RootObject
) = data
->wd_Height
;
3572 DoMethod(current_obj
, MUIM_Layout
);
3573 DoShowMethod(current_obj
);
3575 if (muiGlobalInfo(obj
)->mgi_Prefs
->window_redraw
== WINDOW_REDRAW_WITHOUT_CLEAR
)
3576 MUI_Redraw(current_obj
, MADF_DRAWOBJECT
);
3579 left
= data
->wd_RenderInfo
.mri_Window
->BorderLeft
;
3580 top
= data
->wd_RenderInfo
.mri_Window
->BorderTop
;
3581 width
= data
->wd_RenderInfo
.mri_Window
->Width
3582 - data
->wd_RenderInfo
.mri_Window
->BorderRight
- left
;
3583 height
= data
->wd_RenderInfo
.mri_Window
->Height
3584 - data
->wd_RenderInfo
.mri_Window
->BorderBottom
- top
;
3586 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
3587 left
, top
, width
, height
, left
, top
, 0);
3588 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWALL
);
3591 ActivateObject(data
);
3597 /**************************************************************************
3598 MUIM_AddEventHandler
3599 **************************************************************************/
3600 IPTR
Window__MUIM_AddEventHandler(struct IClass
*cl
, Object
*obj
,
3601 struct MUIP_Window_AddEventHandler
*msg
)
3603 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3605 //D(bug("muimaster.library/window.c: Add Eventhandler %p\n", msg->ehnode));
3608 #if !(AROS_FLAVOUR & AROS_FLAVOUR_BINCOMPAT)
3609 msg
->ehnode
->ehn_Node
.ln_Pri
= msg
->ehnode
->ehn_Priority
;
3611 msg
->ehnode
->ehn_Priority
= msg
->ehnode
->ehn_Priority
;
3614 EnqueueByPriAndAddress((struct List
*)&data
->wd_EHList
, (struct Node
*)msg
->ehnode
);
3615 ChangeEvents(data
, GetDefaultEvents());
3619 /**************************************************************************
3620 MUIM_RemEventHandler
3621 **************************************************************************/
3622 IPTR
Window__MUIM_RemEventHandler(struct IClass
*cl
, Object
*obj
,
3623 struct MUIP_Window_RemEventHandler
*msg
)
3625 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3627 //D(bug("muimaster.library/window.c: Rem Eventhandler %p\n", msg->ehnode));
3629 Remove((struct Node
*)msg
->ehnode
);
3630 ChangeEvents(data
, GetDefaultEvents());
3634 /**************************************************************************
3635 Note that this is MUIM_Window_Setup, not MUIM_Setup
3636 **************************************************************************/
3637 IPTR
Window__MUIM_Setup(struct IClass
*cl
, Object
*obj
, Msg msg
)
3639 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3641 if (!SetupRenderInfo(obj
, data
, &data
->wd_RenderInfo
))
3644 data
->wd_Background
= zune_imspec_setup(MUII_WindowBack
, &data
->wd_RenderInfo
);
3646 if (muiGlobalInfo(obj
)->mgi_Prefs
->window_redraw
== WINDOW_REDRAW_WITH_CLEAR
)
3647 data
->wd_Flags
|= MUIWF_ERASEAREA
;
3652 /**************************************************************************
3654 **************************************************************************/
3655 IPTR
Window__MUIM_Cleanup(struct IClass
*cl
, Object
*obj
, Msg msg
)
3657 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3659 zune_imspec_cleanup(data
->wd_Background
);
3663 DeleteDragNDrop(data
->wd_dnd
);
3664 data
->wd_dnd
= NULL
;
3667 CleanupRenderInfo(obj
, data
, &data
->wd_RenderInfo
);
3672 /**************************************************************************
3673 This adds the the control char handler and also do the MUIA_CycleChain
3674 stuff. Orginal MUI does this in an other way.
3675 **************************************************************************/
3676 IPTR
Window__MUIM_AddControlCharHandler(struct IClass
*cl
, Object
*obj
,
3677 struct MUIP_Window_AddControlCharHandler
*msg
)
3679 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3680 struct ObjNode
*node
;
3682 if (msg
->ccnode
->ehn_Events
)
3685 #if !(AROS_FLAVOUR & AROS_FLAVOUR_BINCOMPAT)
3686 msg
->ccnode
->ehn_Node
.ln_Pri
= msg
->ccnode
->ehn_Priority
;
3688 msg
->ccnode
->ehn_Priority
= msg
->ccnode
->ehn_Priority
;
3691 Enqueue((struct List
*)&data
->wd_CCList
, (struct Node
*)msg
->ccnode
);
3693 /* Due to the lack of a better idea ... */
3694 if (muiAreaData(msg
->ccnode
->ehn_Object
)->mad_Flags
& MADF_CYCLECHAIN
)
3696 node
= AllocPooled(data
->wd_MemoryPool
, sizeof(struct ObjNode
));
3699 node
->obj
= msg
->ccnode
->ehn_Object
;
3700 AddTail((struct List
*)&data
->wd_CycleChain
,(struct Node
*)node
);
3706 /**************************************************************************
3707 MUIM_RemControlCharHandler
3708 **************************************************************************/
3709 IPTR
Window__MUIM_RemControlCharHandler(struct IClass
*cl
, Object
*obj
,
3710 struct MUIP_Window_RemControlCharHandler
*msg
)
3712 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3713 struct ObjNode
*node
= FindObjNode(&data
->wd_CycleChain
,msg
->ccnode
->ehn_Object
);
3715 if (msg
->ccnode
->ehn_Events
) Remove((struct Node
*)msg
->ccnode
);
3719 /* Remove from the chain list */
3720 Remove((struct Node
*)node
);
3721 FreePooled(data
->wd_MemoryPool
, node
, sizeof(struct ObjNode
));
3727 /**************************************************************************
3729 **************************************************************************/
3730 IPTR
Window__MUIM_DragObject(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_DragObject
*msg
)
3732 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3735 struct DragNDrop
*dnd
;
3736 struct MUI_DragImage
*di
;
3737 struct BitMapNode
*bmn
;
3739 if (!(dnd
= CreateDragNDropA(NULL
))) return 0;
3740 if (!(di
= (struct MUI_DragImage
*)DoMethod(msg
->obj
,MUIM_CreateDragImage
,-msg
->touchx
,-msg
->touchy
,msg
->flags
)))
3742 DeleteDragNDrop(dnd
);
3747 DoMethod(msg
->obj
,MUIM_DeleteDragImage
, (IPTR
)di
);
3748 DeleteDragNDrop(dnd
);
3752 if (!(bmn
= CreateBitMapNodeA(TAGLIST(
3753 GUI_BitMap
, (IPTR
)di
->bm
,
3754 GUI_LeftOffset
, di
->touchx
,
3755 GUI_TopOffset
, di
->touchy
,
3756 GUI_Width
, di
->width
,
3757 GUI_Height
, di
->height
))))
3759 DoMethod(msg
->obj
, MUIM_DeleteDragImage
, (IPTR
)di
);
3760 DeleteDragNDrop(dnd
);
3764 AttachBitMapNode(dnd
,bmn
);
3766 if (!PrepareDragNDrop(dnd
, data
->wd_RenderInfo
.mri_Screen
))
3768 DoMethod(msg
->obj
,MUIM_DeleteDragImage
, (IPTR
)di
);
3769 DeleteDragNDrop(dnd
);
3773 muiAreaData(msg
->obj
)->mad_Flags
|= MADF_DRAGGING
;
3775 data
->wd_DragObject
= msg
->obj
;
3777 data
->wd_DragImage
= di
;
3783 /**************************************************************************
3785 **************************************************************************/
3786 IPTR
Window__MUIM_AllocGadgetID(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_AllocGadgetID
*msg
)
3788 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3789 struct IDNode
*newnode
;
3791 newnode
= AllocPooled(data
->wd_MemoryPool
, sizeof(struct IDNode
));
3797 if (IsListEmpty((struct List
*)&data
->wd_IDList
))
3800 AddHead((struct List
*)&data
->wd_IDList
, (struct Node
*)&newnode
->node
);
3806 for (mn
= data
->wd_IDList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
3808 struct IDNode
*idn
= (struct IDNode
*)mn
;
3814 Insert((struct List
*)&data
->wd_IDList
, (struct Node
*)&newnode
->node
, (struct Node
*)mn
);
3821 /**************************************************************************
3823 **************************************************************************/
3824 IPTR
Window__MUIM_FreeGadgetID(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_FreeGadgetID
*msg
)
3826 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3829 for (mn
= data
->wd_IDList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
3831 struct IDNode
*idn
= (struct IDNode
*)mn
;
3832 if (msg
->gadgetid
== idn
->id
)
3834 Remove((struct Node
*)idn
);
3835 FreePooled(data
->wd_MemoryPool
, idn
, sizeof(struct IDNode
));
3844 /**************************************************************************
3845 MUIM_Window_GetMenuCheck
3846 **************************************************************************/
3847 IPTR
Window__MUIM_GetMenuCheck(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_GetMenuCheck
*msg
)
3850 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3852 Object
*strip
= data
->wd_ChildMenustrip
;
3853 if (!strip
) strip
= data
->wd_Menustrip
;
3854 if (!strip
) return 0;
3855 if (!(item
= (Object
*)DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
))) return 0;
3856 get(item
,MUIA_Menuitem_Checked
, &stat
);
3860 /**************************************************************************
3861 MUIM_Window_SetMenuCheck
3862 **************************************************************************/
3863 IPTR
Window__MUIM_SetMenuCheck(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_SetMenuCheck
*msg
)
3865 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3867 Object
*strip
= data
->wd_ChildMenustrip
;
3868 if (!strip
) strip
= data
->wd_Menustrip
;
3869 if (!strip
) return 0;
3870 if (!(item
= (Object
*)DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
))) return 0;
3871 set(item
,MUIA_Menuitem_Checked
,msg
->stat
);
3875 /**************************************************************************
3876 MUIM_Window_GetMenuState
3877 **************************************************************************/
3878 IPTR
Window__MUIM_GetMenuState(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_GetMenuState
*msg
)
3881 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3883 Object
*strip
= data
->wd_ChildMenustrip
;
3884 if (!strip
) strip
= data
->wd_Menustrip
;
3885 if (!strip
) return 0;
3886 if (!(item
= (Object
*)DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
))) return 0;
3887 get(item
,MUIA_Menuitem_Enabled
, &stat
);
3891 /**************************************************************************
3892 MUIM_Window_SetMenuState
3893 **************************************************************************/
3894 IPTR
Window__MUIM_SetMenuState(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_SetMenuState
*msg
)
3896 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3898 Object
*strip
= data
->wd_ChildMenustrip
;
3899 if (!strip
) strip
= data
->wd_Menustrip
;
3900 if (!strip
) return 0;
3901 if (!(item
= (Object
*)DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
))) return 0;
3902 set(item
,MUIA_Menuitem_Enabled
,msg
->stat
);
3906 /**************************************************************************
3907 MUIM_Window_DrawBackground
3908 **************************************************************************/
3909 IPTR
Window__MUIM_DrawBackground(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_DrawBackground
*msg
)
3911 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3912 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
3915 // D(bug("%d:zune_imspec_draw(%p) l=%d t=%d w=%d h=%d xo=%d yo=%d\n",
3916 // __LINE__, data->wd_Background, msg->left, msg->top, msg->width,
3917 // msg->height, msg->xoffset, msg->yoffset));
3918 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
3919 msg
->left
, msg
->top
, msg
->width
, msg
->height
,
3920 msg
->xoffset
, msg
->yoffset
, 0);
3924 /**************************************************************************
3926 **************************************************************************/
3927 IPTR
Window__MUIM_ToFront(struct IClass
*cl
, Object
*obj
, Msg msg
)
3929 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3930 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
3933 WindowToFront(data
->wd_RenderInfo
.mri_Window
);
3937 /**************************************************************************
3939 **************************************************************************/
3940 IPTR
Window__MUIM_ToBack(struct IClass
*cl
, Object
*obj
, Msg msg
)
3942 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3943 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
3946 WindowToBack(data
->wd_RenderInfo
.mri_Window
);
3950 /**************************************************************************
3951 MUIM_Window_ScreenToBack
3952 **************************************************************************/
3953 IPTR
Window__MUIM_ScreenToBack(struct IClass
*cl
, Object
*obj
, Msg msg
)
3955 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3956 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
3959 ScreenToBack(data
->wd_RenderInfo
.mri_Screen
);
3963 /**************************************************************************
3964 MUIM_Window_ScreenToFront
3965 **************************************************************************/
3966 IPTR
Window__MUIM_ScreenToFront(struct IClass
*cl
, Object
*obj
, Msg msg
)
3968 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3969 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
3972 ScreenToFront(data
->wd_RenderInfo
.mri_Screen
);
3976 /**************************************************************************
3977 MUIM_Window_ActionIconify
3978 **************************************************************************/
3979 IPTR
Window__MUIM_ActionIconify(struct IClass
*cl
, Object
*obj
, Msg msg
)
3981 set(_app(obj
), MUIA_Application_Iconified
, TRUE
);
3987 /* Loads ENV: prefs, add a Window_ID chunk in the MUIW chunk, if no MUIW chunk
3988 * then create it at the same level as MUIC chunk, save prefs.
3989 * Do the same for ENVARC:
3990 * MUIW chunk layout:
3992 * 00 00 00 30 (chunk length for a single window, 0x30L big endian)
3995 * xx xx yy yy (X, Y)
3996 * ww ww hh hh (Width, Height)
3997 * ax ax ay ay (AltX, AltY)
3998 * aw aw ah ah (AltWidth, AltHeight)
4006 static void RememberWindowPosition(Object
*winobj
, ULONG id
)
4012 /* Loads ENV: prefs, remove our Window_ID chunk from the MUIW chunk, save prefs.
4013 * Do the same for ENVARC:
4014 * This function shouldnt really be in window.c, but rather in a file dealing
4015 * with prefs file stuff.
4017 static void ForgetWindowPosition(Object
*winobj
, ULONG id
)
4023 /**************************************************************************
4024 MUIM_Window_Snapshot
4025 **************************************************************************/
4026 IPTR
Window__MUIM_Snapshot(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_Snapshot
*msg
)
4028 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4029 struct windowpos winp
;
4031 winp
.id
= data
->wd_ID
;
4032 w
=data
->wd_RenderInfo
.mri_Window
;
4035 winp
.x1
= w
->LeftEdge
; winp
.y1
= w
->TopEdge
;
4036 winp
.w1
= w
->GZZWidth
; winp
.h1
= w
->GZZHeight
;
4037 winp
.x2
=0; winp
.x2
=0; winp
.w2
=0; winp
.h2
=0; //to do save alt dims
4039 set(_app(obj
),MUIA_Application_SetWinPos
,&winp
);
4043 RememberWindowPosition(obj
, data
->wd_ID
);
4045 ForgetWindowPosition(obj
, data
->wd_ID
);
4049 /**************************************************************************
4050 MUIM_Window_UpdateMenu
4051 **************************************************************************/
4052 IPTR
Window__MUIM_UpdateMenu(struct IClass
*cl
, Object
*obj
, Msg msg
)
4054 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4056 struct Menu
*menu
= NULL
;
4057 struct NewMenu
*newmenu
= NULL
;
4058 APTR visinfo
= NULL
;
4059 struct Window
*win
=NULL
;
4061 if (data
->wd_Menustrip
) // only open windows can have a menustrip
4063 if ((visinfo
= GetVisualInfoA(data
->wd_RenderInfo
.mri_Screen
, NULL
)))
4065 win
= data
->wd_RenderInfo
.mri_Window
;
4066 ClearMenuStrip(win
);
4069 FreeMenus(data
->wd_Menu
);
4070 data
->wd_Menu
= NULL
;
4073 get(data
->wd_Menustrip
, MUIA_Menuitem_NewMenu
, &newmenu
);
4076 if ((menu
= CreateMenusA(newmenu
, NULL
)))
4078 struct TagItem tags
[] =
4080 { GTMN_NewLookMenus
, TRUE
},
4081 { TAG_DONE
, (IPTR
)NULL
}
4083 LayoutMenusA(menu
, visinfo
, tags
);
4084 data
->wd_Menu
= menu
;
4085 SetMenuStrip(win
, menu
);
4088 FreeVisualInfo(visinfo
);
4095 /**************************************************************************
4096 MUIM_Export : to export an objects "contents" to a dataspace object.
4097 **************************************************************************/
4098 static IPTR
Window__MUIM_Export(struct IClass
*cl
, Object
*obj
, struct MUIP_Export
*msg
)
4100 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4101 DoMethodA(data
->wd_RootObject
, (Msg
)msg
);
4106 /**************************************************************************
4107 MUIM_Import : to import an objects "contents" from a dataspace object.
4108 **************************************************************************/
4109 static IPTR
Window__MUIM_Import(struct IClass
*cl
, Object
*obj
, struct MUIP_Import
*msg
)
4111 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4112 DoMethodA(data
->wd_RootObject
, (Msg
)msg
);
4116 BOOPSI_DISPATCHER(IPTR
, Window_Dispatcher
, cl
, obj
, msg
)
4118 switch (msg
->MethodID
)
4120 case OM_NEW
: return Window__OM_NEW(cl
, obj
, (struct opSet
*) msg
);
4121 case OM_DISPOSE
: return Window__OM_DISPOSE(cl
, obj
, msg
);
4122 case OM_SET
: return Window__OM_SET(cl
, obj
, (struct opSet
*)msg
);
4123 case OM_GET
: return Window__OM_GET(cl
, obj
, (struct opGet
*)msg
);
4124 case MUIM_FindUData
: return Window__MUIM_FindUData(cl
, obj
, (struct MUIP_FindUData
*)msg
);
4125 case MUIM_GetUData
: return Window__MUIM_GetUData(cl
, obj
, (struct MUIP_GetUData
*)msg
);
4126 case MUIM_SetUData
: return Window__MUIM_SetUData(cl
, obj
, (struct MUIP_SetUData
*)msg
);
4127 case MUIM_SetUDataOnce
: return Window__MUIM_SetUDataOnce(cl
, obj
, (struct MUIP_SetUDataOnce
*)msg
);
4128 case MUIM_Window_AddEventHandler
: return Window__MUIM_AddEventHandler(cl
, obj
, (APTR
)msg
);
4129 case MUIM_Window_RemEventHandler
: return Window__MUIM_RemEventHandler(cl
, obj
, (APTR
)msg
);
4130 case MUIM_ConnectParent
: return Window__MUIM_ConnectParent(cl
, obj
, (APTR
)msg
);
4131 case MUIM_DisconnectParent
: return Window__MUIM_DisconnectParent(cl
, obj
, (APTR
)msg
);
4132 case MUIM_Window_RecalcDisplay
: return Window__MUIM_RecalcDisplay(cl
, obj
, (APTR
)msg
);
4133 case MUIM_Window_Setup
: return Window__MUIM_Setup(cl
, obj
, (APTR
)msg
);
4134 case MUIM_Window_Cleanup
: return Window__MUIM_Cleanup(cl
, obj
, (APTR
)msg
);
4135 case MUIM_Window_AddControlCharHandler
: return Window__MUIM_AddControlCharHandler(cl
, obj
, (APTR
)msg
);
4136 case MUIM_Window_RemControlCharHandler
: return Window__MUIM_RemControlCharHandler(cl
, obj
, (APTR
)msg
);
4137 case MUIM_Window_DragObject
: return Window__MUIM_DragObject(cl
, obj
, (APTR
)msg
);
4138 case MUIM_Window_AllocGadgetID
: return Window__MUIM_AllocGadgetID(cl
, obj
, (APTR
)msg
);
4139 case MUIM_Window_FreeGadgetID
: return Window__MUIM_FreeGadgetID(cl
, obj
, (APTR
)msg
);
4140 case MUIM_Window_GetMenuCheck
: return Window__MUIM_GetMenuCheck(cl
, obj
, (APTR
)msg
);
4141 case MUIM_Window_SetMenuCheck
: return Window__MUIM_SetMenuCheck(cl
, obj
, (APTR
)msg
);
4142 case MUIM_Window_GetMenuState
: return Window__MUIM_GetMenuState(cl
, obj
, (APTR
)msg
);
4143 case MUIM_Window_SetMenuState
: return Window__MUIM_SetMenuState(cl
, obj
, (APTR
)msg
);
4144 case MUIM_Window_DrawBackground
: return Window__MUIM_DrawBackground(cl
, obj
, (APTR
)msg
);
4145 case MUIM_Window_ToFront
: return Window__MUIM_ToFront(cl
, obj
, (APTR
)msg
);
4146 case MUIM_Window_ToBack
: return Window__MUIM_ToBack(cl
, obj
, (APTR
)msg
);
4147 case MUIM_Window_ScreenToFront
: return Window__MUIM_ScreenToFront(cl
, obj
, (APTR
)msg
);
4148 case MUIM_Window_ScreenToBack
: return Window__MUIM_ScreenToBack(cl
, obj
, (APTR
)msg
);
4149 case MUIM_Window_ActionIconify
: return Window__MUIM_ActionIconify(cl
, obj
, (APTR
)msg
);
4150 case MUIM_Window_Snapshot
: return Window__MUIM_Snapshot(cl
, obj
, (APTR
)msg
);
4151 case MUIM_Window_UpdateMenu
: return Window__MUIM_UpdateMenu(cl
, obj
, (APTR
)msg
);
4152 case MUIM_Export
: return Window__MUIM_Export(cl
, obj
, (APTR
)msg
);
4153 case MUIM_Import
: return Window__MUIM_Import(cl
, obj
, (APTR
)msg
);
4156 return DoSuperMethodA(cl
, obj
, msg
);
4158 BOOPSI_DISPATCHER_END
4164 const struct __MUIBuiltinClass _MUI_Window_desc
= {
4167 sizeof(struct MUI_WindowData
),
4168 (void*)Window_Dispatcher