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 /* D(bug("_zune_window_resize : dx=%d, dy=%d\n", dx, dy)); */
1163 SizeWindow(win
, dx
, dy
);
1165 /* The following WindowLimits() call doesn't really work because SizeWindow() is async */
1168 win
, data
->wd_MinMax
.MinWidth
+ hborders
,
1169 data
->wd_MinMax
.MinHeight
+ vborders
,
1170 data
->wd_MinMax
.MaxWidth
+ hborders
,
1171 data
->wd_MinMax
.MaxHeight
+ vborders
1177 static void KillHelpBubble(struct MUI_WindowData
*data
, Object
*obj
, BOOL kill_bubblemode
)
1179 if (data
->wd_HelpObject
)
1181 DoMethod(data
->wd_HelpObject
, MUIM_DeleteBubble
, (IPTR
)data
->wd_HelpBubble
);
1182 data
->wd_HelpObject
= NULL
;
1183 data
->wd_HelpBubble
= NULL
;
1186 if (kill_bubblemode
) data
->wd_Flags
&= ~MUIWF_BUBBLEMODE
;
1188 if (data
->wd_Flags
& MUIWF_BUBBLEMODE
)
1190 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_LATER
;
1194 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_FIRST
;
1201 typedef BOOL (*UNDERCHECK_FUNC
)(Object
*obj
);
1203 static BOOL
ShortHelpUnderPointerCheck(Object
*obj
)
1205 return muiAreaData(obj
)->mad_ShortHelp
? TRUE
: FALSE
;
1208 static Object
*ObjectUnderPointer(struct MUI_WindowData
*data
, Object
*obj
,
1209 LONG x
, LONG y
, UNDERCHECK_FUNC func
)
1213 struct MinList
*ChildList
;
1215 if (!(muiAreaData(obj
)->mad_Flags
& MADF_CANDRAW
))
1218 if (!(x
>= _left(obj
) && x
<= _right(obj
)
1219 && y
>= _top(obj
) && y
<= _bottom(obj
)))
1224 if (get(obj
, MUIA_Group_ChildList
, (IPTR
*)&(ChildList
)))
1226 cstate
= (Object
*)ChildList
->mlh_Head
;
1227 while ((child
= NextObject(&cstate
)))
1231 if ((x
>= _left(child
) && x
<= _right(child
)
1233 y
>= _top(child
) && y
<= _bottom(child
))
1235 (ret
= ObjectUnderPointer(data
, child
, x
, y
, func
)))
1242 if (!(*func
)(obj
)) return NULL
;
1247 static BOOL
ContextMenuUnderPointer(struct MUI_WindowData
*data
, Object
*obj
, LONG x
, LONG y
)
1251 struct MinList
*ChildList
= 0;
1253 if (!(x
>= _left(obj
) && x
<= _right(obj
)
1254 && y
>= _top(obj
) && y
<= _bottom(obj
)))
1259 if (get(obj
, MUIA_Group_ChildList
, (IPTR
*)&(ChildList
)) && (ChildList
!= 0))
1262 cstate
= (Object
*)ChildList
->mlh_Head
;
1263 while ((child
= NextObject(&cstate
)))
1265 if ((x
>= _left(child
) && x
<= _right(child
)
1267 y
>= _top(child
) && y
<= _bottom(child
))
1269 (ContextMenuUnderPointer(data
,child
,x
,y
)))
1274 if (!(muiAreaData(obj
)->mad_Flags
& MADF_CANDRAW
))
1276 if (!(muiAreaData(obj
)->mad_ContextMenu
))
1284 static void ActivateObject (struct MUI_WindowData
*data
)
1286 //bug("Window::ActivateObject (dummy) %08lx\n", data->wd_ActiveObject);
1287 // if (FindObjNode(&data->wd_CycleChain, data->wd_ActiveObject))
1288 // DoMethod(data->wd_ActiveObject, MUIM_GoActive);
1290 // data->wd_ActiveObject = NULL;
1291 //activate better string gadgets.Fix from Georg S On ML List
1292 if (FindObjNode(&data
->wd_CycleChain
, data
->wd_ActiveObject
))
1294 if (!(data
->wd_Flags
& MUIWF_OBJECTGOACTIVESENT
))
1296 data
->wd_Flags
|= MUIWF_OBJECTGOACTIVESENT
;
1297 DoMethod(data
->wd_ActiveObject
, MUIM_GoActive
);
1301 data
->wd_ActiveObject
= NULL
;
1307 static void HandleInputEvent(Object
*win
, struct MUI_WindowData
*data
,
1308 struct IntuiMessage
*event
);
1310 /* handle intuimessage while an object is being dragged
1311 * (reply imsg before returning)
1313 void HandleDragging (Object
*oWin
, struct MUI_WindowData
*data
,
1314 struct IntuiMessage
*imsg
)
1316 struct Window
*iWin
;
1317 int finish_drag
= 0;
1319 iWin
= imsg
->IDCMPWindow
;
1321 if (imsg
->Class
== IDCMP_MOUSEMOVE
)
1323 struct Layer
*layer
;
1324 layer
= WhichLayer(&iWin
->WScreen
->LayerInfo
, iWin
->LeftEdge
+ imsg
->MouseX
, iWin
->TopEdge
+ imsg
->MouseY
);
1326 if (data
->wd_DropObject
)
1329 WORD mousex
= imsg
->MouseX
+ iWin
->LeftEdge
- data
->wd_DropWindow
->LeftEdge
;
1330 WORD mousey
= imsg
->MouseY
+ iWin
->TopEdge
- data
->wd_DropWindow
->TopEdge
;
1332 wnd
= _window(data
->wd_DropObject
);
1335 mousex
< _left(data
->wd_DropObject
)
1336 || mousex
> _right(data
->wd_DropObject
)
1337 || mousey
< _top(data
->wd_DropObject
)
1338 || mousey
> _bottom(data
->wd_DropObject
)
1339 || layer
!= wnd
->WLayer
1342 /* We have left the object */
1343 UndrawDragNDrop(data
->wd_dnd
);
1344 DoMethod(data
->wd_DropObject
, MUIM_DragFinish
,(IPTR
)data
->wd_DragObject
);
1345 data
->wd_DropObject
= NULL
;
1347 } /* if (data->wd_DropObject) */
1349 if (!data
->wd_DropObject
)
1351 Object
*dest_wnd
= NULL
;
1353 /* Find out if app has an openend window at this position */
1358 struct MinList
*ChildList
;
1360 get(_app(oWin
), MUIA_Application_WindowList
, (IPTR
*)&(ChildList
));
1361 cstate
= (Object
*)ChildList
->mlh_Head
;
1362 while ((child
= NextObject(&cstate
)))
1365 get(child
, MUIA_Window_Window
,&wnd
);
1368 if (wnd
->WLayer
== layer
)
1370 data
->wd_DropWindow
= wnd
;
1380 get(dest_wnd
, MUIA_Window_RootObject
, (IPTR
*)&root
);
1387 data
->wd_DropObject
= (Object
*) DoMethod
1389 root
, MUIM_DragQueryExtended
,
1390 (IPTR
) data
->wd_DragObject
,
1391 imsg
->MouseX
+ iWin
->LeftEdge
- data
->wd_DropWindow
->LeftEdge
,
1392 imsg
->MouseY
+ iWin
->TopEdge
- data
->wd_DropWindow
->TopEdge
1397 UndrawDragNDrop(data
->wd_dnd
);
1398 DoMethod(data
->wd_DropObject
, MUIM_DragBegin
,(IPTR
)data
->wd_DragObject
);
1401 } /* if (dest_wnd) */
1402 } /* if (!data->wd_DropObject) */
1404 if (data
->wd_DropObject
)
1412 data
->wd_DropObject
, MUIM_DragReport
,
1413 (IPTR
) data
->wd_DragObject
,
1414 imsg
->MouseX
+ iWin
->LeftEdge
- data
->wd_DropWindow
->LeftEdge
,
1415 imsg
->MouseY
+ iWin
->TopEdge
- data
->wd_DropWindow
->TopEdge
,update
1419 case MUIV_DragReport_Abort
:
1420 UndrawDragNDrop(data
->wd_dnd
);
1421 DoMethod(data
->wd_DropObject
, MUIM_DragFinish
,(IPTR
)data
->wd_DragObject
);
1422 data
->wd_DropObject
= NULL
;
1426 case MUIV_DragReport_Continue
: break;
1427 case MUIV_DragReport_Lock
: break; /* NYI */
1428 case MUIV_DragReport_Refresh
:
1429 UndrawDragNDrop(data
->wd_dnd
);
1434 } /* if (data->wd_DropObject) */
1435 DrawDragNDrop(data
->wd_dnd
, imsg
->MouseX
+ iWin
->LeftEdge
, imsg
->MouseY
+ iWin
->TopEdge
);
1436 } /* if (imsg->Class == IDCMP_MOUSEMOVE) */
1438 if (imsg
->Class
== IDCMP_MOUSEBUTTONS
)
1440 if ((imsg
->Code
== MENUDOWN
) || (imsg
->Code
== SELECTUP
))
1442 if (imsg
->Code
== SELECTUP
&& data
->wd_DropObject
)
1444 UndrawDragNDrop(data
->wd_dnd
);
1445 DoMethod(data
->wd_DropObject
, MUIM_DragFinish
, (IPTR
)data
->wd_DragObject
);
1448 data
->wd_DropObject
, MUIM_DragDrop
, (IPTR
)data
->wd_DragObject
,
1449 imsg
->MouseX
+ iWin
->LeftEdge
- data
->wd_DropWindow
->LeftEdge
,
1450 imsg
->MouseY
+ iWin
->TopEdge
- data
->wd_DropWindow
->TopEdge
1452 data
->wd_DropObject
= NULL
;
1454 else if (imsg
->Code
== SELECTUP
)
1456 DoMethod(data
->wd_DragObject
, MUIM_UnknownDropDestination
, imsg
);
1462 if (imsg
->Class
== IDCMP_CLOSEWINDOW
)
1467 UndrawDragNDrop(data
->wd_dnd
);
1468 if (data
->wd_DropObject
)
1470 DoMethod(data
->wd_DropObject
, MUIM_DragFinish
,(IPTR
)data
->wd_DragObject
);
1471 data
->wd_DropObject
= NULL
;
1473 DeleteDragNDrop(data
->wd_dnd
);
1474 DoMethod(data
->wd_DragObject
,MUIM_DeleteDragImage
, (IPTR
)data
->wd_DragImage
);
1475 muiAreaData(data
->wd_DragObject
)->mad_Flags
&= ~MADF_DRAGGING
;
1476 data
->wd_DragImage
= NULL
;
1477 data
->wd_DragObject
= NULL
;
1478 data
->wd_DropWindow
= NULL
;
1479 data
->wd_dnd
= NULL
;
1480 /* stop listening to IDCMP_MOUSEMOVE */
1481 ChangeEvents(data
, GetDefaultEvents());
1483 ReplyMsg((struct Message
*)imsg
);
1486 /* Reply to imsg if handled */
1487 BOOL
HandleWindowEvent (Object
*oWin
, struct MUI_WindowData
*data
,
1488 struct IntuiMessage
*imsg
)
1490 struct Window
*iWin
;
1491 BOOL is_handled
= TRUE
;
1492 BOOL replied
= FALSE
;
1494 iWin
= imsg
->IDCMPWindow
;
1495 switch (imsg
->Class
)
1497 case IDCMP_ACTIVEWINDOW
:
1498 data
->wd_Flags
|= MUIWF_ACTIVE
;
1499 if (data
->wd_OldActive
)
1500 set(oWin
, MUIA_Window_ActiveObject
, data
->wd_OldActive
);
1501 set(oWin
, MUIA_Window_Activate
, TRUE
);
1502 is_handled
= FALSE
; /* forwardable to area event handlers */
1505 case IDCMP_INACTIVEWINDOW
:
1506 KillHelpBubble(data
, oWin
, TRUE
);
1507 if (data
->wd_ActiveObject
)
1509 data
->wd_OldActive
= data
->wd_ActiveObject
;
1510 set(oWin
, MUIA_Window_ActiveObject
, MUIV_Window_ActiveObject_None
);
1512 data
->wd_Flags
&= ~MUIWF_ACTIVE
;
1513 set(oWin
, MUIA_Window_Activate
, FALSE
);
1514 is_handled
= FALSE
; /* forwardable to area event handlers */
1518 ReplyMsg((struct Message
*)imsg
);
1522 int hborders
= iWin
->BorderLeft
+ iWin
->BorderRight
;
1523 int vborders
= iWin
->BorderTop
+ iWin
->BorderBottom
;
1525 /* set window limits according to window contents */
1528 data
->wd_MinMax
.MinWidth
+ hborders
,
1529 data
->wd_MinMax
.MinHeight
+ vborders
,
1530 data
->wd_MinMax
.MaxWidth
+ hborders
,
1531 data
->wd_MinMax
.MaxHeight
+ vborders
1535 if ((iWin
->GZZWidth
!= data
->wd_Width
) || (iWin
->GZZHeight
!= data
->wd_Height
))
1537 data
->wd_Width
= iWin
->GZZWidth
;
1538 data
->wd_Height
= iWin
->GZZHeight
;
1539 DoHideMethod(data
->wd_RootObject
);
1541 if (1) // why only simple refresh? was: if (data->wd_RenderInfo.mri_Window->Flags & WFLG_SIMPLE_REFRESH)
1543 data
->wd_Flags
|= MUIWF_RESIZING
;
1547 _width(data
->wd_RootObject
) = data
->wd_Width
;
1548 _height(data
->wd_RootObject
) = data
->wd_Height
;
1549 DoMethod(data
->wd_RootObject
, MUIM_Layout
);
1550 DoShowMethod(data
->wd_RootObject
);
1552 LONG left
,top
,width
,height
;
1554 left
= data
->wd_RenderInfo
.mri_Window
->BorderLeft
;
1555 top
= data
->wd_RenderInfo
.mri_Window
->BorderTop
,
1556 width
= data
->wd_RenderInfo
.mri_Window
->Width
1557 - data
->wd_RenderInfo
.mri_Window
->BorderRight
- left
;
1558 height
= data
->wd_RenderInfo
.mri_Window
->Height
1559 - data
->wd_RenderInfo
.mri_Window
->BorderBottom
- top
;
1561 // D(bug("%d:zune_imspec_draw(%p) l=%d t=%d w=%d h=%d xo=%d yo=%d\n",
1562 // __LINE__, data->wd_Background, left, top, width,
1563 // height, left, top));
1564 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
1565 left
, top
, width
, height
, left
, top
, 0);
1567 if (muiGlobalInfo(oWin
)->mgi_Prefs
->window_redraw
== WINDOW_REDRAW_WITHOUT_CLEAR
)
1568 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWOBJECT
);
1570 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWALL
);
1571 // but should only draw focus without using MUIM_GoActive !
1572 ActivateObject(data
);
1577 case IDCMP_REFRESHWINDOW
:
1578 ReplyMsg((struct Message
*)imsg
);
1580 if (data
->wd_Flags
& MUIWF_RESIZING
)
1582 //LONG left,top,right,bottom;
1583 if (MUI_BeginRefresh(&data
->wd_RenderInfo
, 0))
1585 MUI_EndRefresh(&data
->wd_RenderInfo
, 0);
1587 RefreshWindowFrame(data
->wd_RenderInfo
.mri_Window
);
1589 data
->wd_Flags
&= ~MUIWF_RESIZING
;
1590 _width(data
->wd_RootObject
) = data
->wd_Width
;
1591 _height(data
->wd_RootObject
) = data
->wd_Height
;
1592 DoMethod(data
->wd_RootObject
, MUIM_Layout
);
1593 DoShowMethod(data
->wd_RootObject
);
1595 if (muiGlobalInfo(oWin
)->mgi_Prefs
->window_redraw
== WINDOW_REDRAW_WITH_CLEAR
)
1597 LONG left
,top
,width
,height
;
1599 left
= data
->wd_RenderInfo
.mri_Window
->BorderLeft
;
1600 top
= data
->wd_RenderInfo
.mri_Window
->BorderTop
,
1601 width
= data
->wd_RenderInfo
.mri_Window
->Width
- data
->wd_RenderInfo
.mri_Window
->BorderRight
- left
;
1602 height
= data
->wd_RenderInfo
.mri_Window
->Height
- data
->wd_RenderInfo
.mri_Window
->BorderBottom
- top
;
1604 if(data
->wd_Flags
& MUIWF_ERASEAREA
)
1606 // D(bug("%d:zune_imspec_draw(%p) l=%d t=%d w=%d h=%d xo=%d yo=%d\n",
1607 // __LINE__, data->wd_Background, left, top, width,
1608 // height, left, top));
1609 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
1610 left
, top
, width
, height
, left
, top
, 0);
1612 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWALL
);
1615 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWOBJECT
);
1616 // but should only draw focus without using MUIM_GoActive !
1617 ActivateObject(data
);
1621 if (MUI_BeginRefresh(&data
->wd_RenderInfo
, 0))
1623 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWALL
);
1624 // but should only draw focus without using MUIM_GoActive !
1625 ActivateObject(data
);
1626 MUI_EndRefresh(&data
->wd_RenderInfo
, 0);
1631 case IDCMP_CLOSEWINDOW
:
1632 ReplyMsg((struct Message
*)imsg
);
1634 set(oWin
, MUIA_Window_CloseRequest
, TRUE
);
1637 case IDCMP_MENUPICK
:
1638 ReplyMsg((struct Message
*)imsg
);
1643 if (MENUNUM(imsg
->Code
) != NOMENU
&& ITEMNUM(imsg
->Code
) != NOITEM
)
1645 struct MenuItem
*item
= ItemAddress(data
->wd_Menu
,imsg
->Code
);
1648 Object
*item_obj
= (Object
*)GTMENUITEM_USERDATA(item
);
1654 if (item
->Flags
& CHECKIT
)
1655 set(item_obj
, MUIA_Menuitem_Checked
, !!(item
->Flags
& CHECKED
));
1657 set(item_obj
, MUIA_Menuitem_Trigger
, (IPTR
)item
);
1659 get(oWin
, MUIA_ApplicationObject
, &app
);
1660 get(item_obj
, MUIA_UserData
, &udata
);
1662 set(app
, MUIA_Application_MenuAction
, udata
);
1663 set(oWin
, MUIA_Window_MenuAction
, udata
);
1664 DoMethod(app
, MUIM_Application_ReturnID
, udata
);
1671 case IDCMP_IDCMPUPDATE
:
1672 is_handled
= FALSE
; /* forwardable to area event handlers */
1673 if (data
->wd_VertProp
|| data
->wd_HorizProp
)
1675 struct TagItem
*tag
;
1676 tag
= FindTagItem(GA_ID
,(struct TagItem
*)imsg
->IAddress
);
1679 /* If there's a propclass object connected to the prop
1680 gadget, the prop gadget's userdata will point to
1681 that propclass object. See classes/prop.c */
1683 if (data
->wd_VertProp
)
1685 if (tag
->ti_Data
== GADGETID(data
->wd_VertProp
))
1688 if (tag
->ti_Data
== GADGETID(data
->wd_UpButton
))
1690 Object
*prop
= (Object
*)((struct Gadget
*)data
->wd_VertProp
)->UserData
;
1692 if (prop
) DoMethod(prop
, MUIM_Prop_Decrease
, 1);
1695 if (tag
->ti_Data
== GADGETID(data
->wd_DownButton
))
1697 Object
*prop
= (Object
*)((struct Gadget
*)data
->wd_VertProp
)->UserData
;
1699 if (prop
) DoMethod(prop
, MUIM_Prop_Increase
, 1);
1704 if (data
->wd_HorizProp
)
1706 if (tag
->ti_Data
== GADGETID(data
->wd_HorizProp
))
1709 if (tag
->ti_Data
== GADGETID(data
->wd_LeftButton
))
1711 Object
*prop
= (Object
*)((struct Gadget
*)data
->wd_HorizProp
)->UserData
;
1713 if (prop
) DoMethod(prop
, MUIM_Prop_Decrease
, 1);
1716 if (tag
->ti_Data
== GADGETID(data
->wd_RightButton
))
1718 Object
*prop
= (Object
*)((struct Gadget
*)data
->wd_HorizProp
)->UserData
;
1720 if (prop
) DoMethod(prop
, MUIM_Prop_Increase
, 1);
1728 case IDCMP_INTUITICKS
:
1729 if (data
->wd_HelpTicker
)
1731 data
->wd_HelpTicker
--;
1733 if (data
->wd_HelpTicker
== 0)
1735 Object
*underobj
= ObjectUnderPointer(data
, data
->wd_RootObject
, imsg
->MouseX
, imsg
->MouseY
,
1736 ShortHelpUnderPointerCheck
);
1738 if (underobj
!= data
->wd_HelpObject
)
1740 if (data
->wd_HelpObject
)
1742 DoMethod(data
->wd_HelpObject
, MUIM_DeleteBubble
, (IPTR
)data
->wd_HelpBubble
);
1744 data
->wd_HelpObject
= NULL
;
1745 data
->wd_HelpBubble
= NULL
;
1750 data
->wd_HelpBubble
= (APTR
)DoMethod(underobj
, MUIM_CreateBubble
,
1751 imsg
->MouseX
, imsg
->MouseY
,
1753 if (data
->wd_HelpBubble
)
1755 data
->wd_HelpObject
= underobj
;
1756 data
->wd_Flags
|= MUIWF_BUBBLEMODE
;
1761 if (data
->wd_Flags
& MUIWF_BUBBLEMODE
)
1763 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_LATER
;
1767 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_FIRST
;
1770 } /* if (data->wd_HelpTicker == 0) */
1772 } /* if (data->wd_HelpTicker) */
1774 is_handled
= FALSE
; /* forwardable to area event handlers */
1777 case IDCMP_MOUSEBUTTONS
:
1778 DoMethod(oWin
,MUIM_Window_Snapshot
,0);
1779 KillHelpBubble(data
, oWin
, TRUE
);
1784 case IDCMP_MOUSEMOVE
:
1785 KillHelpBubble(data
, oWin
, FALSE
);
1792 } /* switch (imsg->Class) */
1794 if (is_handled
&& !replied
)
1795 ReplyMsg((struct Message
*)imsg
);
1800 static ULONG
InvokeEventHandler (struct MUI_EventHandlerNode
*ehn
,
1801 struct IntuiMessage
*event
, ULONG muikey
)
1805 if (!(_flags(ehn
->ehn_Object
) & MADF_CANDRAW
)) return 0;
1806 if (!(_flags(ehn
->ehn_Object
) & MADF_SHOWME
)) return 0;
1811 && event
->Class
== IDCMP_MOUSEBUTTONS
1812 && event
->Code
== SELECTDOWN
1813 && (_flags(ehn
->ehn_Object
) & MADF_INVIRTUALGROUP
)
1817 Here we filter out SELECTDOWN messages if objects is in a virtual
1818 group but the click went out of the virtual group
1820 Object
*obj
= ehn
->ehn_Object
;
1821 Object
*parent
= obj
;
1822 Object
*wnd
= _win(obj
);
1824 while (get(parent
,MUIA_Parent
,(IPTR
*)&parent
))
1827 if (wnd
== parent
) break;
1828 if (_flags(parent
) & MADF_ISVIRTUALGROUP
)
1832 event
->MouseX
< _mleft(parent
)
1833 || event
->MouseX
> _mright(parent
)
1834 || event
->MouseY
< _mtop(parent
)
1835 || event
->MouseY
> _mbottom(parent
)
1845 if (ehn
->ehn_Flags
& MUI_EHF_HANDLEINPUT
)
1847 DoMethod(ehn
->ehn_Object
, MUIM_HandleInput
, (IPTR
)event
, muikey
);
1855 ehn
->ehn_Class
, ehn
->ehn_Object
, MUIM_HandleEvent
,
1859 res
= DoMethod(ehn
->ehn_Object
, MUIM_HandleEvent
, (IPTR
)event
, muikey
);
1864 static void HandleRawkey(Object
*win
, struct MUI_WindowData
*data
,
1865 struct IntuiMessage
*event
)
1868 struct MUI_EventHandlerNode
*ehn
;
1869 struct IntuiMessage imsg_copy
;
1870 struct InputEvent ie
= {0};
1872 LONG muikey
= MUIKEY_NONE
;
1873 Object
*active_object
= NULL
;
1878 KillHelpBubble(data
, win
, BUBBLEHELP_TICKER_FIRST
);
1880 ie
.ie_NextEvent
= NULL
;
1881 ie
.ie_Class
= IECLASS_RAWKEY
;
1883 ie
.ie_Code
= event
->Code
;
1884 ie
.ie_Qualifier
= event
->Qualifier
;
1885 ie
.ie_EventAddress
= (APTR
)*(ULONG
*)event
->IAddress
;
1887 ie
.ie_TimeStamp
.Seconds
= event
->Seconds
;
1888 ie
.ie_TimeStamp
.Microseconds
= event
->Micros
;
1890 ie
.ie_TimeStamp
.tv_secs
= event
->Seconds
;
1891 ie
.ie_TimeStamp
.tv_micro
= event
->Micros
;
1894 set(win
, MUIA_Window_InputEvent
, (IPTR
)&ie
);
1896 /* get the vanilla key for control char */
1899 /* Remove the up prefix as convert key does not convert a upkey event */
1900 msg_code
= event
->Code
;
1901 event
->Code
&= ~IECODE_UP_PREFIX
;
1902 key
= ConvertKey(event
);
1903 event
->Code
= msg_code
;
1907 deadkey
= *(ULONG
*)event
->IAddress
;
1908 imsg_copy
.IAddress
= &deadkey
;
1909 ReplyMsg((struct Message
*)event
);
1912 //bug("rawkey: code=%lx, qual=%lx\n", event->Code, event->Qualifier);
1914 /* check if imsg translate to predefined keystroke */
1916 struct InputEvent ievent
;
1917 BOOL matched
= FALSE
;
1919 ievent
.ie_NextEvent
= NULL
;
1920 ievent
.ie_Class
= IECLASS_RAWKEY
;
1921 ievent
.ie_SubClass
= 0;
1922 ievent
.ie_Code
= event
->Code
;
1923 ievent
.ie_Qualifier
= event
->Qualifier
;
1924 /* ie_EventAddress is not used by MatchIX. If needed, it should be
1925 * ensured that it is still a valid adress because of the shallow
1926 * IntuiMessage copy currently done in _zune_window_message before
1927 * message is replied.
1929 ievent
.ie_EventAddress
= NULL
;
1930 //ievent.ie_EventAddress = (APTR *) *((ULONG *)(event->IAddress));
1932 for (muikey
= MUIKEY_COUNT
- 1; muikey
>= MUIKEY_PRESS
; muikey
--)
1934 if (muiGlobalInfo(win
)->mgi_Prefs
->muikeys
[muikey
].ix_well
!= 0
1935 && MatchIX(&ievent
, &muiGlobalInfo(win
)->mgi_Prefs
->muikeys
[muikey
].ix
))
1944 if (muikey
== MUIKEY_PRESS
&& (event
->Code
& IECODE_UP_PREFIX
))
1945 muikey
= MUIKEY_RELEASE
;
1949 muikey
= MUIKEY_NONE
;
1951 } /* check if imsg translate to predefined keystroke */
1953 if ((muikey
!= MUIKEY_NONE
)
1954 && !(data
->wd_DisabledKeys
& (1<<muikey
)))
1956 D(bug("HandleRawkey: try MUIKEY %ld on window %0x08lx\n", muikey
, win
));
1959 case MUIKEY_PRESS
: break;
1960 case MUIKEY_TOGGLE
: break;
1961 case MUIKEY_UP
: break;
1962 case MUIKEY_DOWN
: break;
1963 case MUIKEY_PAGEUP
: break;
1964 case MUIKEY_PAGEDOWN
: break;
1965 case MUIKEY_TOP
: break;
1966 case MUIKEY_BOTTOM
: break;
1967 case MUIKEY_LEFT
: break;
1968 case MUIKEY_RIGHT
: break;
1969 case MUIKEY_WORDLEFT
: break;
1970 case MUIKEY_WORDRIGHT
: break;
1971 case MUIKEY_LINESTART
: break;
1972 case MUIKEY_LINEEND
: break;
1973 case MUIKEY_GADGET_NEXT
:
1974 set(win
, MUIA_Window_ActiveObject
, MUIV_Window_ActiveObject_Next
);
1976 case MUIKEY_GADGET_PREV
:
1977 set(win
, MUIA_Window_ActiveObject
, MUIV_Window_ActiveObject_Prev
);
1979 case MUIKEY_GADGET_OFF
:
1980 set(win
, MUIA_Window_ActiveObject
, MUIV_Window_ActiveObject_None
);
1982 case MUIKEY_WINDOW_CLOSE
:
1983 set(win
, MUIA_Window_CloseRequest
, TRUE
);
1985 case MUIKEY_WINDOW_NEXT
: break;
1986 case MUIKEY_WINDOW_PREV
: break;
1987 case MUIKEY_HELP
: break;
1988 case MUIKEY_POPUP
: break;
1993 active_object
= NULL
;
1994 if ((data
->wd_ActiveObject
!= NULL
)
1995 && (DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
1996 (IPTR
)data
->wd_ActiveObject
) != (IPTR
)NULL
))
1998 active_object
= data
->wd_ActiveObject
;
1999 get(active_object
, MUIA_Disabled
, &disabled
);
2002 data
->wd_ActiveObject
= NULL
;
2004 /* try ActiveObject */
2005 if ((active_object
!= NULL
) && !disabled
)
2009 ** Which method should be used for muikeys? MUIM_HandleInput or
2010 ** MUIM_HandleEvent. Also note that there is a flag MUI_EHF_ALWAYSKEYS
2011 ** which probably means that all keys events are requested??
2012 ** For now MUIM_HandleEvent is used as this is currently implemented
2013 ** in Area class ;) although I guess it should be MUIM_HandleInput as this
2017 if (muikey
!= MUIKEY_NONE
)
2019 res
= DoMethod(active_object
, MUIM_HandleEvent
, (IPTR
)event
, muikey
);
2020 if (res
& MUI_EventHandlerRC_Eat
) return;
2023 D(bug("HandleRawkey: try active object (%08lx) handlers\n", active_object
));
2025 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2027 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2029 if ((ehn
->ehn_Object
== active_object
)
2030 && ((ehn
->ehn_Events
& IDCMP_RAWKEY
)
2031 || (ehn
->ehn_Flags
& MUI_EHF_ALWAYSKEYS
)))
2033 D(bug("HandleRawkey: (active) invoking on %p (ehn=%p) event=%p muikey=%p\n",
2034 ehn
->ehn_Object
, ehn
, event
, muikey
));
2035 res
= InvokeEventHandler(ehn
, event
, muikey
);
2036 D(bug("HandleRawkey: (active) got res=%d\n", res
));
2037 if (res
& MUI_EventHandlerRC_Eat
)
2040 /* Leave the loop if a different object has been activated */
2041 if (active_object
!= data
->wd_ActiveObject
)
2044 } /* for (mn = data->wd_EHList.mlh_Head; mn->mln_Succ; mn = mn->mln_Succ) */
2046 // event not eaten by active object, try its parents
2047 // this is to implement popup key in Popstring
2048 if (active_object
== data
->wd_ActiveObject
)
2050 Object
*current_obj
= active_object
;
2052 D(bug("HandleRawkey: try active object parents handlers\n"));
2053 while (current_obj
!= NULL
)
2055 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2057 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2059 if ((ehn
->ehn_Object
== current_obj
)
2060 && ((ehn
->ehn_Events
& IDCMP_RAWKEY
)
2061 || (ehn
->ehn_Flags
& MUI_EHF_ALWAYSKEYS
)))
2063 //D(bug("HandleRawkey: (active parents) invoking on %p (ehn=%p) "
2064 //"event=%p muikey=%p\n",
2065 //ehn->ehn_Object, ehn, event, muikey));
2066 res
= InvokeEventHandler(ehn
, event
, muikey
);
2067 //D(bug("HandleRawkey: (active parents) got res=%d\n", res));
2068 if (res
& MUI_EventHandlerRC_Eat
)
2071 /* Leave the loop if a different object has been activated */
2072 if (active_object
!= data
->wd_ActiveObject
)
2076 current_obj
= (Object
*)XGET(current_obj
, MUIA_Parent
);
2077 } // while (current_obj != NULL)
2081 } /* if (active_object && !disabled) */
2083 D(bug("HandleRawkey: try default object handlers\n"));
2085 /* try DefaultObject */
2086 if (data
->wd_DefaultObject
!= NULL
)
2087 get(data
->wd_DefaultObject
, MUIA_Disabled
, &disabled
);
2089 if ((data
->wd_DefaultObject
!= NULL
) && !disabled
2090 && (active_object
!= data
->wd_DefaultObject
))
2092 /* No, we only should do this if the object actually has requested this via RequestIDCMP()! */
2093 // if (muikey != MUIKEY_NONE && (_flags(data->wd_DefaultObject) & MADF_CANDRAW))
2095 // DoMethod(data->wd_DefaultObject, MUIM_HandleInput, event, muikey);
2099 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2101 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2103 if ((ehn
->ehn_Object
== data
->wd_DefaultObject
)
2104 && ((ehn
->ehn_Events
& IDCMP_RAWKEY
)
2105 || (ehn
->ehn_Flags
& MUI_EHF_ALWAYSKEYS
)))
2107 //D(bug("HandleRawkey: (default) invoking on %p (ehn=%p) event=%p muikey=%p\n",
2108 //ehn->ehn_Object, ehn, event, muikey));
2109 res
= InvokeEventHandler(ehn
, event
, muikey
);
2110 //D(bug("HandleRawkey: (default) got res=%d\n", res));
2111 if (res
& MUI_EventHandlerRC_Eat
)
2116 } /* if ... default object */
2118 D(bug("HandleRawkey: try other handlers\n"));
2120 // try other handlers
2121 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2123 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2125 // skip Active and Default object as they have already been
2127 if (ehn
->ehn_Object
== data
->wd_ActiveObject
2128 || ehn
->ehn_Object
== data
->wd_DefaultObject
)
2131 if (ehn
->ehn_Events
& IDCMP_RAWKEY
)
2133 //D(bug("HandleRawkey: (others) invoking on %p (ehn=%p) event=%p muikey=%p\n",
2134 //ehn->ehn_Object, ehn, event, muikey));
2135 res
= InvokeEventHandler(ehn
, event
, MUIKEY_NONE
);
2136 //D(bug("HandleRawkey: (others) got res=%d\n", res));
2137 if (res
& MUI_EventHandlerRC_Eat
)
2140 } /* for (mn = data->wd_EHList.mlh_Head; mn->mln_Succ; mn = mn->mln_Succ) */
2142 D(bug("HandleRawkey: try control chars handlers\n"));
2144 /* try Control Chars */
2145 //bug("ctrlchar, key='%c' code=0x%08lx\n", key, event->Code);
2148 for (mn
= data
->wd_CCList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2150 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2152 if (ehn
->ehn_Events
== key
)
2155 LONG muikey2
= ehn
->ehn_Flags
;
2157 get(ehn
->ehn_Object
, MUIA_Disabled
, &disabled
);
2161 //bug("control char\n");
2162 if (event
->Code
& IECODE_UP_PREFIX
)
2164 /* simulate a release */
2165 if (muikey2
== MUIKEY_PRESS
)
2166 muikey2
= MUIKEY_RELEASE
;
2171 if ((muikey2
!= MUIKEY_NONE
)
2172 && (_flags(ehn
->ehn_Object
) & MADF_CANDRAW
)
2173 && (_flags(ehn
->ehn_Object
) & MADF_SHOWME
))
2177 ehn
->ehn_Class
, ehn
->ehn_Object
, MUIM_HandleEvent
,
2180 if (res
& MUI_EventHandlerRC_Eat
)
2185 } /* try control chars */
2188 /* forward non-keystroke events to event handlers */
2189 static void HandleInputEvent(Object
*win
, struct MUI_WindowData
*data
,
2190 struct IntuiMessage
*event
)
2193 struct MUI_EventHandlerNode
*ehn
;
2194 struct IntuiMessage imsg_copy
;
2196 ULONG mask
= event
->Class
;
2198 if (mask
!= IDCMP_IDCMPUPDATE
)
2201 imsg_copy
.IAddress
= NULL
; /* be sure to trap access to that */
2202 ReplyMsg((struct Message
*)event
);
2206 if (mask
== IDCMP_MOUSEMOVE
)
2208 struct Window
*iWin
;
2209 iWin
= event
->IDCMPWindow
;
2211 if (ContextMenuUnderPointer (data
, data
->wd_RootObject
,
2212 event
->MouseX
, event
->MouseY
))
2214 iWin
->Flags
|= WFLG_RMBTRAP
;
2216 else if (!data
->wd_NoMenus
)
2218 iWin
->Flags
&= ~WFLG_RMBTRAP
;
2222 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2224 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2226 if (ehn
->ehn_Events
& mask
)
2230 get(ehn
->ehn_Object
, MUIA_Disabled
, &disabled
);
2234 res
= InvokeEventHandler(ehn
, event
, MUIKEY_NONE
);
2235 if (res
& MUI_EventHandlerRC_Eat
)
2241 if (mask
== IDCMP_IDCMPUPDATE
)
2242 ReplyMsg((struct Message
*)event
);
2246 /* process window message, this does a ReplyMsg() to the message */
2247 /* Called from application.c */
2248 void _zune_window_message(struct IntuiMessage
*imsg
)
2250 struct Window
*iWin
;
2252 struct MUI_WindowData
*data
;
2255 iWin
= imsg
->IDCMPWindow
;
2256 oWin
= (Object
*)iWin
->UserData
;
2257 data
= muiWindowData(oWin
);
2259 if (data
->wd_DragObject
)
2261 HandleDragging(oWin
, data
, imsg
);
2265 handled
= HandleWindowEvent(oWin
, data
, imsg
);
2268 if (IDCMP_RAWKEY
== imsg
->Class
)
2269 HandleRawkey(oWin
, data
, imsg
);
2270 else if (IDCMP_GADGETUP
== imsg
->Class
)
2273 if (ETI_MUI
== ((struct Gadget
*) imsg
->IAddress
)->GadgetID
)
2275 DoMethod(_app(oWin
), MUIM_Application_OpenConfigWindow
);
2281 HandleInputEvent(oWin
, data
, imsg
);
2287 /******************************************************************************/
2288 /******************************************************************************/
2290 /* code for setting MUIA_Window_RootObject */
2291 static void ChangeRootObject (struct MUI_WindowData
*data
, Object
*obj
,
2296 ASSERT_VALID_PTR(data
);
2297 ASSERT_VALID_PTR(obj
);
2299 oldRoot
= data
->wd_RootObject
;
2300 if (!(data
->wd_Flags
& MUIWF_OPENED
))
2304 if (data
->wd_ActiveObject
== oldRoot
)
2305 set(obj
, MUIA_Window_ActiveObject
, MUIV_Window_ActiveObject_None
);
2306 DoMethod(oldRoot
, MUIM_DisconnectParent
);
2309 data
->wd_RootObject
= newRoot
;
2312 /* if window is in App tree, inform child */
2313 if (muiNotifyData(obj
)->mnd_GlobalInfo
)
2314 DoMethod(newRoot
, MUIM_ConnectParent
, (IPTR
)obj
);
2319 // find the ObjNode containing a pointer to the given object
2320 // currently only used for cycle chain objects
2321 static struct ObjNode
*FindObjNode(struct MinList
*list
, Object
*obj
)
2323 struct ObjNode
*node
;
2325 ASSERT_VALID_PTR(list
);
2330 ASSERT_VALID_PTR(obj
);
2332 for (node
= (struct ObjNode
*)list
->mlh_Head
;
2333 node
->node
.mln_Succ
;
2334 node
= (struct ObjNode
*)node
->node
.mln_Succ
)
2336 if (node
->obj
== obj
)
2344 static Object
*GetFirstActiveObject (struct MUI_WindowData
*data
)
2346 ASSERT_VALID_PTR(data
);
2348 if (!IsListEmpty((struct List
*)&data
->wd_CycleChain
))
2349 return ((struct ObjNode
*)data
->wd_CycleChain
.mlh_Head
)->obj
;
2354 static Object
*GetLastActiveObject (struct MUI_WindowData
*data
)
2356 ASSERT_VALID_PTR(data
);
2358 if (!IsListEmpty((struct List
*)&data
->wd_CycleChain
))
2359 return ((struct ObjNode
*)data
->wd_CycleChain
.mlh_TailPred
)->obj
;
2364 typedef struct ObjNode
*objnode_iterator_t(struct ObjNode
*curr_node
);
2366 static objnode_iterator_t NextObjNodeIterator
;
2367 static objnode_iterator_t PrevObjNodeIterator
;
2369 static struct ObjNode
*NextObjNodeIterator (struct ObjNode
*curr_node
)
2371 if (curr_node
->node
.mln_Succ
->mln_Succ
)
2372 return (struct ObjNode
*)curr_node
->node
.mln_Succ
;
2377 static struct ObjNode
*PrevObjNodeIterator (struct ObjNode
*curr_node
)
2379 if (curr_node
->node
.mln_Pred
->mln_Pred
)
2380 return (struct ObjNode
*)curr_node
->node
.mln_Pred
;
2385 static Object
*GetPrevNextActiveObject (struct ObjNode
*old_activenode
, objnode_iterator_t node_iterator
)
2387 struct ObjNode
*curr_node
;
2388 struct ObjNode
*node
;
2391 ASSERT_VALID_PTR(old_activenode
);
2393 curr_node
= old_activenode
;
2399 node
= node_iterator(curr_node
);
2404 /* let's see if this obj meets cycle requirements (enabled & visible) */
2409 get(obj
, MUIA_Disabled
, &is_disabled
);
2411 if (!is_disabled
&& (_flags(obj
) & MADF_SHOWME
))
2425 /**************************************************************************
2426 Code for setting MUIA_Window_ActiveObject
2428 - remove focus drawing for current active object
2429 - find (if needed) the new active object
2430 - set data->wd_ActiveObject to the new object
2431 - draw focus around the new active object
2432 **************************************************************************/
2433 static void SetActiveObject (struct MUI_WindowData
*data
, Object
*obj
, IPTR newval
)
2435 struct ObjNode
*old_activenode
= NULL
;
2437 ASSERT_VALID_PTR(data
);
2438 ASSERT_VALID_PTR(obj
);
2440 D(bug("MUIC_Window:SetActiveObject(data, obj, %08lx) Active=%p\n",
2441 newval
, data
->wd_ActiveObject
));
2443 if ((data
->wd_ActiveObject
!= NULL
)
2444 && (DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
2445 (IPTR
)data
->wd_ActiveObject
) != (IPTR
)NULL
))
2447 if ((IPTR
)data
->wd_ActiveObject
== newval
)
2449 old_activenode
= FindObjNode(&data
->wd_CycleChain
, data
->wd_ActiveObject
);
2450 //if (_flags(data->wd_ActiveObject) & MADF_CANDRAW)
2451 if (data
->wd_Flags
& MUIWF_OBJECTGOACTIVESENT
)
2453 DoMethod(data
->wd_ActiveObject
, MUIM_GoInactive
);
2457 data
->wd_ActiveObject
= NULL
;
2458 data
->wd_Flags
&= ~MUIWF_OBJECTGOACTIVESENT
;
2462 case MUIV_Window_ActiveObject_None
:
2465 case MUIV_Window_ActiveObject_Next
:
2466 if (old_activenode
!= NULL
)
2467 data
->wd_ActiveObject
= GetPrevNextActiveObject(old_activenode
,
2468 NextObjNodeIterator
);
2469 if (NULL
== data
->wd_ActiveObject
)
2470 data
->wd_ActiveObject
= GetFirstActiveObject(data
);
2473 case MUIV_Window_ActiveObject_Prev
:
2475 data
->wd_ActiveObject
= GetPrevNextActiveObject(old_activenode
,
2476 PrevObjNodeIterator
);
2477 if (NULL
== data
->wd_ActiveObject
)
2478 data
->wd_ActiveObject
= GetLastActiveObject(data
);
2482 data
->wd_ActiveObject
= (Object
*)newval
;
2486 if (data
->wd_ActiveObject
!= NULL
2487 && DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
2488 (IPTR
)data
->wd_ActiveObject
)
2489 && (_flags(data
->wd_ActiveObject
) & MADF_CANDRAW
))
2491 DoMethod(data
->wd_ActiveObject
, MUIM_GoActive
);
2492 data
->wd_Flags
|= MUIWF_OBJECTGOACTIVESENT
;
2498 * calculate real dimensions from programmer requirements.
2499 * may be overridden by user settings if MUIA_Window_ID is set.
2501 /* MUIV_Window_Height_Screen and MUIV_Window_Height_Visible
2502 * are not handled yet, as their Width couterparts.
2504 static void WindowSelectDimensions (struct MUI_WindowData
*data
)
2506 if (!data
->wd_Width
)
2508 if (data
->wd_ReqWidth
> 0) data
->wd_Width
= data
->wd_ReqWidth
;
2509 else if (data
->wd_ReqWidth
== MUIV_Window_Width_Default
)
2510 data
->wd_Width
= data
->wd_MinMax
.DefWidth
;
2511 else if (_between(MUIV_Window_Width_MinMax(100),
2513 MUIV_Window_Width_MinMax(0)))
2515 data
->wd_Width
= data
->wd_MinMax
.MinWidth
2517 * (data
->wd_MinMax
.MaxWidth
- data
->wd_MinMax
.MinWidth
);
2519 else if (_between(MUIV_Window_Width_Screen(100),
2521 MUIV_Window_Width_Screen(0)))
2523 data
->wd_Width
= data
->wd_RenderInfo
.mri_ScreenWidth
2524 * (- (data
->wd_ReqWidth
+ 200)) / 100;
2526 else if (_between(MUIV_Window_Width_Visible(100),
2528 MUIV_Window_Width_Visible(0)))
2530 data
->wd_Width
= data
->wd_RenderInfo
.mri_ScreenWidth
2531 * (- (data
->wd_ReqWidth
+ 100)) / 100;
2534 if (data
->wd_ReqHeight
> 0) data
->wd_Height
= data
->wd_ReqHeight
;
2535 else if (data
->wd_ReqHeight
== MUIV_Window_Height_Default
)
2536 data
->wd_Height
= data
->wd_MinMax
.DefHeight
;
2537 else if (_between(MUIV_Window_Height_MinMax(100),
2539 MUIV_Window_Height_MinMax(0)))
2541 data
->wd_Height
= data
->wd_MinMax
.MinHeight
2542 - data
->wd_ReqHeight
2543 * (data
->wd_MinMax
.MaxHeight
- data
->wd_MinMax
.MinHeight
);
2545 else if (_between(MUIV_Window_Height_Screen(100),
2547 MUIV_Window_Height_Screen(0)))
2552 scr
= data
->wd_RenderInfo
.mri_Screen
;
2554 height
= scr
->Height
- data
->wd_RenderInfo
.mri_BorderTop
- data
->wd_RenderInfo
.mri_BorderBottom
;
2556 /* This is new to Zune: If TopEdge Delta is requested
2557 * the screenheight doesn't cover the barlayer */
2558 if (data
->wd_Y
<= MUIV_Window_TopEdge_Delta(0))
2559 height
-= scr
->BarHeight
+ 1;
2561 data
->wd_Height
= height
* (- (data
->wd_ReqHeight
+ 200)) / 100;
2563 else if (_between(MUIV_Window_Height_Visible(100),
2565 MUIV_Window_Height_Visible(0)))
2567 data
->wd_Height
= data
->wd_RenderInfo
.mri_ScreenHeight
2568 * (- (data
->wd_ReqHeight
+ 100)) / 100;
2572 if (data
->wd_ReqWidth
== MUIV_Window_Width_Scaled
)
2573 data
->wd_Width
= data
->wd_Height
* data
->wd_MinMax
.MinWidth
2574 / data
->wd_MinMax
.MinHeight
;
2575 else if (data
->wd_ReqHeight
== MUIV_Window_Width_Scaled
)
2576 data
->wd_Height
= data
->wd_Width
* data
->wd_MinMax
.MinHeight
2577 / data
->wd_MinMax
.MinWidth
;
2579 data
->wd_Width
= CLAMP(data
->wd_Width
, data
->wd_MinMax
.MinWidth
,
2580 data
->wd_MinMax
.MaxWidth
);
2581 data
->wd_Height
= CLAMP(data
->wd_Height
, data
->wd_MinMax
.MinHeight
,
2582 data
->wd_MinMax
.MaxHeight
);
2586 /**************************************************************************
2588 **************************************************************************/
2589 IPTR
Window__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
2591 struct MUI_WindowData
*data
;
2592 struct TagItem
*tags
,*tag
;
2594 obj
= (Object
*)DoSuperMethodA(cl
, obj
, (Msg
)msg
);
2598 /* Initial local instance data */
2599 data
= INST_DATA(cl
, obj
);
2601 data
->wd_MemoryPool
= CreatePool(0, 4096, 2048);
2602 if (NULL
== data
->wd_MemoryPool
)
2604 CoerceMethod(cl
, obj
, OM_DISPOSE
);
2608 data
->wd_RenderInfo
.mri_WindowObject
= obj
;
2610 NewList((struct List
*)&(data
->wd_EHList
));
2611 NewList((struct List
*)&(data
->wd_CCList
));
2612 NewList((struct List
*)&(data
->wd_CycleChain
));
2613 NewList((struct List
*)&(data
->wd_IDList
));
2615 data
->wd_CrtFlags
= WFLG_SIZEGADGET
| WFLG_DRAGBAR
| WFLG_DEPTHGADGET
2616 | WFLG_CLOSEGADGET
| WFLG_SIMPLE_REFRESH
2617 | WFLG_REPORTMOUSE
| WFLG_NEWLOOKMENUS
;
2618 data
->wd_ZoomGadget
= TRUE
;
2619 data
->wd_Events
= GetDefaultEvents();
2620 data
->wd_ActiveObject
= NULL
;
2622 data
->wd_ReqHeight
= MUIV_Window_Height_Default
;
2623 data
->wd_ReqWidth
= MUIV_Window_Width_Default
;
2624 data
->wd_RootObject
= NULL
;
2625 data
->wd_DefaultObject
= NULL
;
2627 /* alternate dimensions */
2628 /* no change in coordinates */
2629 data
->wd_AltDim
.Top
= MUIV_Window_AltTopEdge_NoChange
;
2630 data
->wd_AltDim
.Left
= MUIV_Window_AltLeftEdge_NoChange
;
2631 /* default to min size */
2632 data
->wd_AltDim
.Width
= MUIV_Window_AltWidth_MinMax(0);
2633 data
->wd_AltDim
.Height
= MUIV_Window_AltHeight_MinMax(0);
2634 data
->wd_X
= MUIV_Window_LeftEdge_Centered
;
2635 data
->wd_Y
= MUIV_Window_TopEdge_Centered
;
2636 data
->wd_DisabledKeys
= 0L;
2637 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_FIRST
;
2639 /* parse initial taglist */
2641 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
)); )
2643 switch (tag
->ti_Tag
)
2645 case MUIA_Window_EraseArea
:
2646 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_ERASEAREA
);
2649 case MUIA_Window_ToolBox
:
2650 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_TOOLBOX
);
2653 case MUIA_Window_CloseGadget
:
2654 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_CLOSEGADGET
);
2657 case MUIA_Window_SizeGadget
:
2658 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_SIZEGADGET
);
2661 case MUIA_Window_ZoomGadget
:
2662 data
->wd_ZoomGadget
= tag
->ti_Data
;
2665 case MUIA_Window_Backdrop
:
2666 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_BACKDROP
);
2669 case MUIA_Window_Borderless
:
2670 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_BORDERLESS
);
2673 case MUIA_Window_DepthGadget
:
2674 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_DEPTHGADGET
);
2677 case MUIA_Window_DragBar
:
2678 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_DRAGBAR
);
2681 case MUIA_Window_SizeRight
:
2682 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_SIZEBRIGHT
);
2685 case MUIA_Window_Height
:
2686 data
->wd_ReqHeight
= (LONG
)tag
->ti_Data
;
2689 case MUIA_Window_Width
:
2690 data
->wd_ReqWidth
= (LONG
)tag
->ti_Data
;
2693 case MUIA_Window_ID
:
2694 set(obj
, MUIA_Window_ID
, tag
->ti_Data
);
2697 case MUIA_Window_IsSubWindow
:
2698 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_ISSUBWINDOW
);
2701 case MUIA_Window_Title
:
2702 set(obj
, MUIA_Window_Title
, tag
->ti_Data
);
2705 case MUIA_Window_ScreenTitle
:
2706 set(obj
, MUIA_Window_ScreenTitle
, tag
->ti_Data
);
2709 case MUIA_Window_Activate
:
2710 _handle_bool_tag(data
->wd_Flags
, !tag
->ti_Data
, MUIWF_DONTACTIVATE
);
2713 case MUIA_Window_DefaultObject
:
2714 set(obj
, MUIA_Window_DefaultObject
, tag
->ti_Data
);
2717 case MUIA_Window_Menustrip
:
2718 data
->wd_ChildMenustrip
= (Object
*)tag
->ti_Data
;
2721 case MUIA_Window_NoMenus
:
2722 data
->wd_NoMenus
= (BOOL
) tag
->ti_Data
;
2725 case MUIA_Window_RootObject
:
2728 CoerceMethod(cl
, obj
, OM_DISPOSE
);
2731 set(obj
, MUIA_Window_RootObject
, tag
->ti_Data
);
2734 case MUIA_Window_AltHeight
:
2735 data
->wd_AltDim
.Height
= (WORD
)tag
->ti_Data
;
2738 case MUIA_Window_AltWidth
:
2739 data
->wd_AltDim
.Width
= (WORD
)tag
->ti_Data
;
2742 case MUIA_Window_AltLeftEdge
:
2743 data
->wd_AltDim
.Left
= (WORD
)tag
->ti_Data
;
2746 case MUIA_Window_AltTopEdge
:
2747 data
->wd_AltDim
.Top
= (WORD
)tag
->ti_Data
;
2750 case MUIA_Window_AppWindow
:
2751 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_ISAPPWINDOW
);
2754 case MUIA_Window_LeftEdge
:
2755 data
->wd_X
= tag
->ti_Data
;
2758 case MUIA_Window_TopEdge
:
2759 data
->wd_Y
= tag
->ti_Data
;
2762 case MUIA_Window_UseBottomBorderScroller
:
2763 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_USEBOTTOMSCROLLER
);
2766 case MUIA_Window_UseRightBorderScroller
:
2767 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_USERIGHTSCROLLER
);
2770 case MUIA_Window_DisableKeys
:
2771 data
->wd_DisabledKeys
= tag
->ti_Data
;
2774 case MUIA_Window_RefWindow
:
2775 data
->wd_RefWindow
= (Object
*)tag
->ti_Data
;
2778 case MUIA_Window_Screen
:
2779 data
->wd_UserScreen
= (struct Screen
*)tag
->ti_Data
;
2782 case MUIA_Window_PublicScreen
:
2783 data
->wd_UserPublicScreen
= (STRPTR
)tag
->ti_Data
;
2788 /* D(bug("muimaster.library/window.c: Window Object created at 0x%lx back=%lx\n", */
2789 /* obj,data->wd_Background)); */
2794 /**************************************************************************
2796 **************************************************************************/
2797 IPTR
Window__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
2799 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
2801 /* D(bug("Window_Dispose(%p)\n", obj)); */
2803 #if 0 /* We no longer clear muiGlobalInfo() during disconnections, so
2804 this can cause problems (remove object which is already removed).
2805 Furthermore AFAIK it is not legal to dispose a window object
2806 which is still ocnnected to the application object, anyway. */
2808 if (muiGlobalInfo(obj
) && _app(obj
))
2810 /* D(bug(" Window_Dispose(%p) : calling app->OM_REMMEMBER\n", obj)); */
2811 DoMethod(_app(obj
), OM_REMMEMBER
, (IPTR
)obj
);
2815 if (data
->wd_RootObject
)
2816 MUI_DisposeObject(data
->wd_RootObject
);
2818 if (data
->wd_ChildMenustrip
)
2819 MUI_DisposeObject(data
->wd_ChildMenustrip
);
2821 if (data
->wd_Title
) FreeVec(data
->wd_Title
);
2822 if (data
->wd_ScreenTitle
)FreeVec(data
->wd_ScreenTitle
);
2824 DeletePool(data
->wd_MemoryPool
);
2826 /* D(bug(" Window_Dispose(%p) : calling supermethod\n", obj)); */
2827 return DoSuperMethodA(cl
, obj
, msg
);
2830 static ULONG
WindowOpen(struct IClass
*cl
, Object
*obj
);
2831 static ULONG
WindowClose(struct IClass
*cl
, Object
*obj
);
2833 /**************************************************************************
2835 **************************************************************************/
2836 IPTR
Window__OM_SET(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
2838 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
2839 struct TagItem
*tags
= msg
->ops_AttrList
;
2840 const struct TagItem
*tag
;
2842 while ((tag
= NextTagItem(&tags
)) != NULL
)
2844 switch (tag
->ti_Tag
)
2846 case MUIA_Window_Activate
:
2847 if (data
->wd_RenderInfo
.mri_Window
)
2849 if (tag
->ti_Data
&& !(data
->wd_Flags
& MUIWF_ACTIVE
))
2851 ActivateWindow(data
->wd_RenderInfo
.mri_Window
);
2852 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_ACTIVE
);
2856 _handle_bool_tag(data
->wd_Flags
, !tag
->ti_Data
, MUIWF_DONTACTIVATE
);
2859 case MUIA_Window_ActiveObject
:
2860 /* D(bug("MUIA_Window_ActiveObject %ld (%p)\n", tag->ti_Data, tag->ti_Data)); */
2861 SetActiveObject(data
, obj
, tag
->ti_Data
);
2864 case MUIA_Window_DefaultObject
:
2865 data
->wd_DefaultObject
= (APTR
)tag
->ti_Data
;
2868 case MUIA_Window_ID
:
2869 data
->wd_ID
= tag
->ti_Data
;
2872 case MUIA_Window_IsSubWindow
:
2873 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_ISSUBWINDOW
);
2876 case MUIA_Window_Open
:
2879 if (data
->wd_Flags
& MUIWF_HIDDEN
)
2880 data
->wd_Flags
|= MUIWF_OPENONUNHIDE
;
2882 if (!(data
->wd_Flags
& MUIWF_OPENED
))
2883 WindowOpen(cl
, obj
);
2886 DoMethod(obj
, MUIM_Window_ToFront
);
2887 set(obj
, MUIA_Window_Activate
, TRUE
);
2891 if (data
->wd_Flags
& MUIWF_HIDDEN
)
2892 data
->wd_Flags
&= ~MUIWF_OPENONUNHIDE
;
2894 if (data
->wd_Flags
& MUIWF_OPENED
)
2895 WindowClose(cl
, obj
);
2898 case MUIA_ShowMe
: /* PRIVATE *abuse* of the Area's ShowMe attr */
2903 if (data
->wd_Flags
& MUIWF_HIDDEN
)
2905 data
->wd_Flags
&= ~MUIWF_HIDDEN
;
2907 if (data
->wd_Flags
& MUIWF_OPENONUNHIDE
)
2909 data
->wd_Flags
&= ~MUIWF_OPENONUNHIDE
;
2910 set(obj
, MUIA_Window_Open
, TRUE
);
2918 if (data
->wd_Flags
& MUIWF_OPENED
)
2920 data
->wd_Flags
|= MUIWF_OPENONUNHIDE
;
2922 set(obj
, MUIA_Window_Open
, FALSE
);
2925 data
->wd_Flags
|= MUIWF_HIDDEN
;
2929 case MUIA_Window_RootObject
:
2930 ChangeRootObject(data
, obj
, (Object
*)tag
->ti_Data
);
2933 case MUIA_Window_Title
:
2934 if (data
->wd_Title
) FreeVec(data
->wd_Title
);
2935 data
->wd_Title
= StrDup((STRPTR
)tag
->ti_Data
);
2936 if (data
->wd_RenderInfo
.mri_Window
)
2937 SetWindowTitles(data
->wd_RenderInfo
.mri_Window
,data
->wd_Title
, (CONST_STRPTR
)~0);
2940 case MUIA_Window_ScreenTitle
:
2941 if (data
->wd_ScreenTitle
) FreeVec(data
->wd_ScreenTitle
);
2942 data
->wd_ScreenTitle
= StrDup((STRPTR
)tag
->ti_Data
);
2943 if (data
->wd_RenderInfo
.mri_Window
)
2944 SetWindowTitles(data
->wd_RenderInfo
.mri_Window
,
2945 (CONST_STRPTR
)~0, data
->wd_ScreenTitle
);
2948 case MUIA_Window_NoMenus
:
2949 data
->wd_NoMenus
= (BOOL
) tag
->ti_Data
;
2950 if (data
->wd_RenderInfo
.mri_Window
)
2952 if (data
->wd_NoMenus
)
2953 data
->wd_RenderInfo
.mri_Window
->Flags
|= WFLG_RMBTRAP
;
2955 data
->wd_RenderInfo
.mri_Window
->Flags
&= ~WFLG_RMBTRAP
;
2960 case MUIA_Window_UseBottomBorderScroller
:
2961 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_USEBOTTOMSCROLLER
);
2964 case MUIA_Window_UseRightBorderScroller
:
2965 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_USERIGHTSCROLLER
);
2968 case MUIA_Window_DisableKeys
:
2969 data
->wd_DisabledKeys
= tag
->ti_Data
;
2972 case MUIA_Window_RefWindow
:
2973 data
->wd_RefWindow
= (Object
*)tag
->ti_Data
;
2976 #warning "TODO: obsolete hacked atribute - remove"
2977 #if defined(MUIA_Window_WandererBackdrop)
2978 case MUIA_Window_WandererBackdrop
:
2979 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_BACKDROP
);
2980 _handle_bool_tag(data
->wd_CrtFlags
, !tag
->ti_Data
, WFLG_DRAGBAR
);
2981 _handle_bool_tag(data
->wd_CrtFlags
, !tag
->ti_Data
, WFLG_SIZEGADGET
);
2982 _handle_bool_tag(data
->wd_CrtFlags
, !tag
->ti_Data
, WFLG_CLOSEGADGET
);
2983 _handle_bool_tag(data
->wd_CrtFlags
, !tag
->ti_Data
, WFLG_DEPTHGADGET
);
2984 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_BORDERLESS
);
2987 data
->wd_ReqWidth
= (LONG
)MUIV_Window_Width_Screen(100);
2988 /* won't take the barlayer into account */
2989 data
->wd_ReqHeight
= (LONG
)MUIV_Window_Height_Screen(100);
2991 data
->wd_Height
= 0;
2992 data
->wd_X
= (LONG
)0;
2993 /* place the window below the bar layer */
2994 data
->wd_Y
= (LONG
)MUIV_Window_TopEdge_Delta(0);
2999 case MUIA_Window_LeftEdge
:
3000 data
->wd_X
= tag
->ti_Data
;
3003 case MUIA_Window_TopEdge
:
3004 data
->wd_Y
= tag
->ti_Data
;
3007 case MUIA_Window_Width
:
3008 data
->wd_ReqWidth
= (LONG
)tag
->ti_Data
;
3009 data
->wd_Width
= 0; /* otherwise windowselectdimensions() ignores ReqWidth */
3012 case MUIA_Window_Height
:
3013 data
->wd_ReqHeight
= (LONG
)tag
->ti_Data
;
3014 data
->wd_Height
= 0;
3017 case MUIA_Window_Screen
:
3018 data
->wd_UserScreen
= (struct Screen
*)tag
->ti_Data
;
3021 case MUIA_Window_PublicScreen
:
3022 data
->wd_UserPublicScreen
= (STRPTR
)tag
->ti_Data
;
3029 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
3032 /**************************************************************************
3034 **************************************************************************/
3035 IPTR
Window__OM_GET(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
3037 #define STORE *(msg->opg_Storage)
3039 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3043 switch(msg
->opg_AttrID
)
3045 case MUIA_Window_Activate
:
3046 STORE
= (data
->wd_Flags
& (MUIWF_ACTIVE
| MUIWF_OPENED
)) == (MUIWF_ACTIVE
| MUIWF_OPENED
);
3049 case MUIA_Window_Window
:
3050 STORE
= (IPTR
)data
->wd_RenderInfo
.mri_Window
;
3053 case MUIA_Window_Screen
:
3054 STORE
= (IPTR
)data
->wd_RenderInfo
.mri_Screen
;
3057 case MUIA_Window_PublicScreen
:
3058 STORE
= (IPTR
)data
->wd_UserPublicScreen
;
3061 case MUIA_Window_ActiveObject
:
3062 if ((data
->wd_ActiveObject
!= NULL
)
3063 && (DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
3064 (IPTR
)data
->wd_ActiveObject
) != (IPTR
)NULL
))
3065 STORE
= (IPTR
)data
->wd_ActiveObject
;
3070 case MUIA_Window_CloseRequest
:
3074 case MUIA_Window_DefaultObject
:
3075 STORE
= (IPTR
)data
->wd_DefaultObject
;
3078 case MUIA_Window_DisableKeys
:
3079 STORE
= data
->wd_DisabledKeys
;
3082 case MUIA_Window_Height
:
3083 STORE
= (IPTR
)data
->wd_Height
;
3086 case MUIA_Window_ID
:
3087 STORE
= data
->wd_ID
;
3090 case MUIA_Window_IsSubWindow
:
3091 STORE
= (data
->wd_Flags
& MUIWF_ISSUBWINDOW
) == MUIWF_ISSUBWINDOW
;
3094 case MUIA_Window_LeftEdge
:
3095 if (data
->wd_RenderInfo
.mri_Window
)
3096 STORE
= (IPTR
)data
->wd_RenderInfo
.mri_Window
->LeftEdge
;
3101 case MUIA_Window_Open
:
3102 STORE
= (data
->wd_Flags
& MUIWF_OPENED
) == MUIWF_OPENED
;
3105 case MUIA_Window_RootObject
:
3106 STORE
= (IPTR
)data
->wd_RootObject
;
3109 case MUIA_Window_ScreenTitle
:
3110 STORE
= (IPTR
)data
->wd_ScreenTitle
;
3113 case MUIA_Window_Title
:
3114 STORE
= (IPTR
)data
->wd_Title
;
3117 case MUIA_Window_TopEdge
:
3118 if (data
->wd_RenderInfo
.mri_Window
)
3119 STORE
= (IPTR
)data
->wd_RenderInfo
.mri_Window
->TopEdge
;
3124 case MUIA_Window_Width
:
3125 STORE
= (IPTR
)data
->wd_Width
;
3137 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
3142 * MUIM_FindUData : tests if the MUIA_UserData of the object
3143 * contains the given <udata> and returns the object pointer in this case.
3145 IPTR
Window__MUIM_FindUData(struct IClass
*cl
, Object
*obj
, struct MUIP_FindUData
*msg
)
3147 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3149 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3152 if (data
->wd_RootObject
)
3153 return DoMethodA(data
->wd_RootObject
, (Msg
)msg
);
3160 * MUIM_GetUData : This method tests if the MUIA_UserData of the object
3161 * contains the given <udata> and gets <attr> to <storage> for itself
3164 IPTR
Window__MUIM_GetUData(struct IClass
*cl
, Object
*obj
, struct MUIP_GetUData
*msg
)
3166 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3168 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3170 get(obj
, msg
->attr
, msg
->storage
);
3174 if (data
->wd_RootObject
)
3175 return DoMethodA(data
->wd_RootObject
, (Msg
)msg
);
3182 * MUIM_SetUData : This method tests if the MUIA_UserData of the object
3183 * contains the given <udata> and sets <attr> to <val> for itself in this case.
3185 IPTR
Window__MUIM_SetUData(struct IClass
*cl
, Object
*obj
, struct MUIP_SetUData
*msg
)
3187 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3189 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3190 set(obj
, msg
->attr
, msg
->val
);
3192 if (data
->wd_RootObject
)
3193 DoMethodA(data
->wd_RootObject
, (Msg
)msg
);
3200 * MUIM_SetUDataOnce : This method tests if the MUIA_UserData of the object
3201 * contains the given <udata> and sets <attr> to <val> for itself in this case.
3203 IPTR
Window__MUIM_SetUDataOnce(struct IClass
*cl
, Object
*obj
, struct MUIP_SetUDataOnce
*msg
)
3205 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3207 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3209 set(obj
, msg
->attr
, msg
->val
);
3213 if (data
->wd_RootObject
)
3214 return DoMethodA(data
->wd_RootObject
, (Msg
)msg
);
3219 /**************************************************************************
3220 Called by Application (parent) object whenever this object is added.
3222 **************************************************************************/
3223 IPTR
Window__MUIM_ConnectParent(struct IClass
*cl
, Object
*obj
,
3224 struct MUIP_ConnectParent
*msg
)
3226 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3228 if (!DoSuperMethodA(cl
,obj
,(Msg
)msg
)) return 0;
3230 if (data
->wd_RootObject
)
3231 DoMethod(data
->wd_RootObject
, MUIM_ConnectParent
, (IPTR
)obj
);
3233 if (data
->wd_ChildMenustrip
)
3234 DoMethod(data
->wd_ChildMenustrip
, MUIM_ConnectParent
, (IPTR
)obj
);
3240 /**************************************************************************
3241 called by parent object
3242 **************************************************************************/
3243 IPTR
Window__MUIM_DisconnectParent(struct IClass
*cl
, Object
*obj
, struct MUIP_DisconnectParent
*msg
)
3245 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3247 /* D(bug("Window_DisconnectParent(%p) : muiGlobalInfo=%p\n", muiGlobalInfo(obj))); */
3248 if (muiGlobalInfo(obj
))
3250 /* Close the window before disconnecting all the childs */
3251 if ((data
->wd_Flags
& MUIWF_OPENED
))
3253 /* D(bug(" Window_DisconnectParent(%p) : closing window\n", muiGlobalInfo(obj))); */
3254 set(obj
, MUIA_Window_Open
, FALSE
);
3256 if (data
->wd_ChildMenustrip
)
3257 DoMethod(data
->wd_ChildMenustrip
, MUIM_DisconnectParent
, (IPTR
)obj
);
3259 if (data
->wd_RootObject
)
3260 DoMethodA(data
->wd_RootObject
, (Msg
)msg
);
3262 /* D(bug(" Window_DisconnectParent(%p) : calling supermethod\n", muiGlobalInfo(obj))); */
3263 return DoSuperMethodA(cl
,obj
,(Msg
)msg
);
3271 static void SetRootObjInnerSpacing(Object
*obj
, struct MUI_WindowData
*data
)
3273 UWORD wd_innerLeft
, wd_innerRight
, wd_innerTop
, wd_innerBottom
;
3275 if (data
->wd_CrtFlags
& WFLG_BORDERLESS
)
3284 wd_innerLeft
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_left
;
3285 wd_innerRight
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_right
;
3286 wd_innerTop
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_top
;
3287 wd_innerBottom
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_bottom
;
3290 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERLEFT
))
3292 muiAreaData(data
->wd_RootObject
)->mad_InnerLeft
= wd_innerLeft
;
3295 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERTOP
))
3297 muiAreaData(data
->wd_RootObject
)->mad_InnerTop
= wd_innerTop
;
3300 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERRIGHT
))
3302 muiAreaData(data
->wd_RootObject
)->mad_InnerRight
= wd_innerRight
;
3305 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERBOTTOM
))
3307 muiAreaData(data
->wd_RootObject
)->mad_InnerBottom
= wd_innerBottom
;
3312 * Called before window is opened or resized. It determines its bounds,
3313 * so you can call WindowSelectDimensions() to find the final dims.
3315 static void WindowMinMax(Object
*obj
, struct MUI_WindowData
*data
)
3317 SetRootObjInnerSpacing(obj
, data
);
3318 /* inquire about sizes */
3319 DoMethod(data
->wd_RootObject
, MUIM_AskMinMax
, (IPTR
)&data
->wd_MinMax
);
3320 /* D(bug("*** root minmax = %ld,%ld => %ld,%ld\n", data->wd_MinMax.MinWidth, */
3321 /* data->wd_MinMax.MinHeight, */
3322 /* data->wd_MinMax.MaxWidth, data->wd_MinMax.MaxHeight)); */
3323 __area_finish_minmax(data
->wd_RootObject
, &data
->wd_MinMax
);
3324 /* D(bug("*** root minmax2 = %ld,%ld => %ld,%ld\n", data->wd_MinMax.MinWidth, */
3325 /* data->wd_MinMax.MinHeight, */
3326 /* data->wd_MinMax.MaxWidth, data->wd_MinMax.MaxHeight)); */
3330 static void InstallBackbuffer (struct IClass
*cl
, Object
*obj
)
3332 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3334 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
3336 data
->wd_RenderInfo
.mri_BufferBM
=
3337 AllocBitMap(win
->Width
, win
->Height
, win
->RPort
->BitMap
->Depth
,
3338 0, win
->RPort
->BitMap
);
3340 if (data
->wd_RenderInfo
.mri_BufferBM
)
3342 /* D(bug("install_backbuffer : allocated bitmap %dx%dx%d with friend %p\n", */
3343 /* win->Width, win->Height, win->RPort->BitMap->Depth, win->RPort->BitMap)); */
3344 InitRastPort(&data
->wd_RenderInfo
.mri_BufferRP
);
3345 data
->wd_RenderInfo
.mri_BufferRP
.BitMap
= data
->wd_RenderInfo
.mri_BufferBM
;
3349 static void DeinstallBackbuffer (struct IClass
*cl
, Object
*obj
)
3351 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3353 if (data
->wd_RenderInfo
.mri_BufferBM
)
3355 DeinitRastPort(&data
->wd_RenderInfo
.mri_BufferRP
);
3356 FreeBitMap(data
->wd_RenderInfo
.mri_BufferBM
);
3357 data
->wd_RenderInfo
.mri_BufferBM
= NULL
;
3362 * Called after window is opened or resized.
3363 * An expose event is already queued, it will trigger
3364 * MUIM_Draw for us when going back to main loop.
3366 static void WindowShow (struct IClass
*cl
, Object
*obj
)
3368 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3369 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
3370 /* D(bug("window_show %s %d\n", __FILE__, __LINE__)); */
3372 _left(data
->wd_RootObject
) = win
->BorderLeft
;
3373 _top(data
->wd_RootObject
) = win
->BorderTop
;
3374 _width(data
->wd_RootObject
) = data
->wd_Width
;
3375 _height(data
->wd_RootObject
) = data
->wd_Height
;
3377 DoMethod(data
->wd_RootObject
, MUIM_Layout
);
3379 ShowRenderInfo(&data
->wd_RenderInfo
);
3380 /* D(bug("zune_imspec_show %s %d\n", __FILE__, __LINE__)); */
3381 zune_imspec_show(data
->wd_Background
, obj
);
3382 DoShowMethod(data
->wd_RootObject
);
3385 static ULONG
WindowOpen(struct IClass
*cl
, Object
*obj
)
3387 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3389 if (!data
->wd_RootObject
)
3392 if (!DoMethod(obj
, MUIM_Window_Setup
))
3395 /* I got display info, so calculate your display dependant data */
3396 if (!DoSetupMethod(data
->wd_RootObject
, &data
->wd_RenderInfo
))
3398 DoMethod(obj
, MUIM_Window_Cleanup
);
3402 /* inquire about sizes */
3403 WindowMinMax(obj
,data
);
3404 WindowSelectDimensions(data
);
3406 /* Decide which menustrip should be used */
3407 if (!data
->wd_ChildMenustrip
)
3408 get(_app(obj
), MUIA_Application_Menustrip
, (IPTR
*)&data
->wd_Menustrip
);
3410 data
->wd_Menustrip
= data
->wd_ChildMenustrip
;
3412 /* open window here ... */
3413 if (!DisplayWindow(obj
,data
))
3415 /* free display dependant data */
3416 data
->wd_Menustrip
= NULL
;
3417 DoMethod(data
->wd_RootObject
, MUIM_Cleanup
);
3418 DoMethod(obj
, MUIM_Window_Cleanup
);
3422 InstallBackbuffer(cl
, obj
);
3424 data
->wd_Flags
|= MUIWF_OPENED
;
3426 WindowShow(cl
, obj
);
3429 LONG left
,top
,width
,height
;
3431 left
= data
->wd_RenderInfo
.mri_Window
->BorderLeft
;
3432 top
= data
->wd_RenderInfo
.mri_Window
->BorderTop
,
3433 width
= data
->wd_RenderInfo
.mri_Window
->Width
3434 - data
->wd_RenderInfo
.mri_Window
->BorderRight
- left
;
3435 height
= data
->wd_RenderInfo
.mri_Window
->Height
3436 - data
->wd_RenderInfo
.mri_Window
->BorderBottom
- top
;
3438 /* D(bug("zune_imspec_draw %s %d\n", __FILE__, __LINE__)); */
3439 // D(bug("%d:zune_imspec_draw(%p) l=%d t=%d w=%d h=%d xo=%d yo=%d\n",
3440 // __LINE__, data->wd_Background, left, top, width,
3441 // height, left, top));
3443 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
3444 left
, top
, width
, height
, left
, top
, 0);
3447 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWOBJECT
);
3449 D(bug("MUIC_Window:windowOpen() ActiveObject=%p\n", data
->wd_ActiveObject
));
3450 if (data
->wd_OldActive
!= NULL
)
3452 set(obj
, MUIA_Window_ActiveObject
, data
->wd_OldActive
);
3458 /******************************************************************************/
3459 /******************************************************************************/
3461 static ULONG
WindowClose(struct IClass
*cl
, Object
*obj
)
3463 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3465 if (data
->wd_ActiveObject
!= NULL
)
3467 data
->wd_OldActive
= data
->wd_ActiveObject
;
3468 set(obj
, MUIA_Window_ActiveObject
, MUIV_Window_ActiveObject_None
);
3471 KillHelpBubble(data
, obj
, BUBBLEHELP_TICKER_FIRST
);
3473 /* remove from window */
3474 DoHideMethod(data
->wd_RootObject
);
3475 zune_imspec_hide(data
->wd_Background
);
3477 DeinstallBackbuffer(cl
, obj
);
3479 HideRenderInfo(&data
->wd_RenderInfo
);
3481 /* close here ... */
3482 UndisplayWindow(obj
,data
);
3484 data
->wd_Flags
&= ~MUIWF_OPENED
;
3485 data
->wd_Menustrip
= NULL
;
3487 /* free display dependant data */
3488 DoMethod(data
->wd_RootObject
, MUIM_Cleanup
);
3489 DoMethod(obj
, MUIM_Window_Cleanup
);
3493 /* calculate a new layout
3495 * see Group_ExitChange
3499 IPTR
Window__MUIM_RecalcDisplay(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_RecalcDisplay
*msg
)
3501 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3502 LONG left
,top
,width
,height
;
3504 Object
*current_obj
;
3506 if (!(data
->wd_Flags
& MUIWF_OPENED
))
3509 current_obj
= msg
->originator
;
3511 // typically originator is a group which has been added/removed a child
3512 // calculate minmax of current obj
3513 // if new minmax can accomodate current obj size, stop
3514 // else try with its parent
3515 // the resulting object will get a new layout
3516 // it currently produces some redundant AskMinMax but allows
3517 // to not always relayout the whole window
3519 D(bug("RecalcDisplay on %p\n", current_obj
));
3520 while (current_obj
!= NULL
)
3522 DoMethod(current_obj
, MUIM_AskMinMax
, (IPTR
)&muiAreaData(current_obj
)->mad_MinMax
);
3523 __area_finish_minmax(current_obj
, &muiAreaData(current_obj
)->mad_MinMax
);
3525 D(bug("size w = %d, h = %d\n", _width(current_obj
), _height(current_obj
)));
3526 D(bug("new w = %d-%d, h = %d-%d\n", _minwidth(current_obj
), _maxwidth(current_obj
),
3527 _minheight(current_obj
), _maxheight(current_obj
)));
3529 if (!_between(_minwidth(current_obj
), _width(current_obj
), _maxwidth(current_obj
))
3530 || !_between(_minheight(current_obj
), _height(current_obj
), _maxheight(current_obj
)))
3532 current_obj
= _parent(current_obj
);
3533 D(bug("RecalcDisplay, try parent %p\n", current_obj
));
3537 D(bug("found it\n"));
3543 current_obj
= data
->wd_RootObject
;
3545 WindowMinMax(obj
, data
);
3546 DoHideMethod(current_obj
);
3547 /* resize window ? */
3548 WindowSelectDimensions(data
);
3549 resized
= WindowResize(data
);
3552 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
3553 _left(data
->wd_RootObject
) = win
->BorderLeft
;
3554 _top(data
->wd_RootObject
) = win
->BorderTop
;
3555 _width(data
->wd_RootObject
) = data
->wd_Width
;
3556 _height(data
->wd_RootObject
) = data
->wd_Height
;
3558 DoMethod(current_obj
, MUIM_Layout
);
3559 DoShowMethod(current_obj
);
3561 if (muiGlobalInfo(obj
)->mgi_Prefs
->window_redraw
== WINDOW_REDRAW_WITHOUT_CLEAR
)
3562 MUI_Redraw(current_obj
, MADF_DRAWOBJECT
);
3565 left
= data
->wd_RenderInfo
.mri_Window
->BorderLeft
;
3566 top
= data
->wd_RenderInfo
.mri_Window
->BorderTop
;
3567 width
= data
->wd_RenderInfo
.mri_Window
->Width
3568 - data
->wd_RenderInfo
.mri_Window
->BorderRight
- left
;
3569 height
= data
->wd_RenderInfo
.mri_Window
->Height
3570 - data
->wd_RenderInfo
.mri_Window
->BorderBottom
- top
;
3572 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
3573 left
, top
, width
, height
, left
, top
, 0);
3574 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWALL
);
3577 ActivateObject(data
);
3583 /**************************************************************************
3584 MUIM_AddEventHandler
3585 **************************************************************************/
3586 IPTR
Window__MUIM_AddEventHandler(struct IClass
*cl
, Object
*obj
,
3587 struct MUIP_Window_AddEventHandler
*msg
)
3589 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3591 //D(bug("muimaster.library/window.c: Add Eventhandler %p\n", msg->ehnode));
3594 #if !(AROS_FLAVOUR & AROS_FLAVOUR_BINCOMPAT)
3595 msg
->ehnode
->ehn_Node
.ln_Pri
= msg
->ehnode
->ehn_Priority
;
3597 msg
->ehnode
->ehn_Priority
= msg
->ehnode
->ehn_Priority
;
3600 EnqueueByPriAndAddress((struct List
*)&data
->wd_EHList
, (struct Node
*)msg
->ehnode
);
3601 ChangeEvents(data
, GetDefaultEvents());
3605 /**************************************************************************
3606 MUIM_RemEventHandler
3607 **************************************************************************/
3608 IPTR
Window__MUIM_RemEventHandler(struct IClass
*cl
, Object
*obj
,
3609 struct MUIP_Window_RemEventHandler
*msg
)
3611 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3613 //D(bug("muimaster.library/window.c: Rem Eventhandler %p\n", msg->ehnode));
3615 Remove((struct Node
*)msg
->ehnode
);
3616 ChangeEvents(data
, GetDefaultEvents());
3620 /**************************************************************************
3621 Note that this is MUIM_Window_Setup, not MUIM_Setup
3622 **************************************************************************/
3623 IPTR
Window__MUIM_Setup(struct IClass
*cl
, Object
*obj
, Msg msg
)
3625 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3627 if (!SetupRenderInfo(obj
, data
, &data
->wd_RenderInfo
))
3630 data
->wd_Background
= zune_imspec_setup(MUII_WindowBack
, &data
->wd_RenderInfo
);
3632 if (muiGlobalInfo(obj
)->mgi_Prefs
->window_redraw
== WINDOW_REDRAW_WITH_CLEAR
)
3633 data
->wd_Flags
|= MUIWF_ERASEAREA
;
3638 /**************************************************************************
3640 **************************************************************************/
3641 IPTR
Window__MUIM_Cleanup(struct IClass
*cl
, Object
*obj
, Msg msg
)
3643 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3645 zune_imspec_cleanup(data
->wd_Background
);
3649 DeleteDragNDrop(data
->wd_dnd
);
3650 data
->wd_dnd
= NULL
;
3653 CleanupRenderInfo(obj
, data
, &data
->wd_RenderInfo
);
3658 /**************************************************************************
3659 This adds the the control char handler and also do the MUIA_CycleChain
3660 stuff. Orginal MUI does this in an other way.
3661 **************************************************************************/
3662 IPTR
Window__MUIM_AddControlCharHandler(struct IClass
*cl
, Object
*obj
,
3663 struct MUIP_Window_AddControlCharHandler
*msg
)
3665 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3666 struct ObjNode
*node
;
3668 if (msg
->ccnode
->ehn_Events
)
3671 #if !(AROS_FLAVOUR & AROS_FLAVOUR_BINCOMPAT)
3672 msg
->ccnode
->ehn_Node
.ln_Pri
= msg
->ccnode
->ehn_Priority
;
3674 msg
->ccnode
->ehn_Priority
= msg
->ccnode
->ehn_Priority
;
3677 Enqueue((struct List
*)&data
->wd_CCList
, (struct Node
*)msg
->ccnode
);
3679 /* Due to the lack of a better idea ... */
3680 if (muiAreaData(msg
->ccnode
->ehn_Object
)->mad_Flags
& MADF_CYCLECHAIN
)
3682 node
= AllocPooled(data
->wd_MemoryPool
, sizeof(struct ObjNode
));
3685 node
->obj
= msg
->ccnode
->ehn_Object
;
3686 AddTail((struct List
*)&data
->wd_CycleChain
,(struct Node
*)node
);
3692 /**************************************************************************
3693 MUIM_RemControlCharHandler
3694 **************************************************************************/
3695 IPTR
Window__MUIM_RemControlCharHandler(struct IClass
*cl
, Object
*obj
,
3696 struct MUIP_Window_RemControlCharHandler
*msg
)
3698 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3699 struct ObjNode
*node
= FindObjNode(&data
->wd_CycleChain
,msg
->ccnode
->ehn_Object
);
3701 if (msg
->ccnode
->ehn_Events
) Remove((struct Node
*)msg
->ccnode
);
3705 /* Remove from the chain list */
3706 Remove((struct Node
*)node
);
3707 FreePooled(data
->wd_MemoryPool
, node
, sizeof(struct ObjNode
));
3713 /**************************************************************************
3715 **************************************************************************/
3716 IPTR
Window__MUIM_DragObject(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_DragObject
*msg
)
3718 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3721 struct DragNDrop
*dnd
;
3722 struct MUI_DragImage
*di
;
3723 struct BitMapNode
*bmn
;
3725 if (!(dnd
= CreateDragNDropA(NULL
))) return 0;
3726 if (!(di
= (struct MUI_DragImage
*)DoMethod(msg
->obj
,MUIM_CreateDragImage
,-msg
->touchx
,-msg
->touchy
,msg
->flags
)))
3728 DeleteDragNDrop(dnd
);
3733 DoMethod(msg
->obj
,MUIM_DeleteDragImage
, (IPTR
)di
);
3734 DeleteDragNDrop(dnd
);
3738 if (!(bmn
= CreateBitMapNode(NULL
, /* dummy */
3740 GUI_LeftOffset
, di
->touchx
,
3741 GUI_TopOffset
, di
->touchy
,
3742 GUI_Width
, di
->width
,
3743 GUI_Height
, di
->height
,
3746 DoMethod(msg
->obj
, MUIM_DeleteDragImage
, (IPTR
)di
);
3747 DeleteDragNDrop(dnd
);
3751 AttachBitMapNode(dnd
,bmn
);
3753 if (!PrepareDragNDrop(dnd
, data
->wd_RenderInfo
.mri_Screen
))
3755 DoMethod(msg
->obj
,MUIM_DeleteDragImage
, (IPTR
)di
);
3756 DeleteDragNDrop(dnd
);
3760 muiAreaData(msg
->obj
)->mad_Flags
|= MADF_DRAGGING
;
3762 data
->wd_DragObject
= msg
->obj
;
3764 data
->wd_DragImage
= di
;
3770 /**************************************************************************
3772 **************************************************************************/
3773 IPTR
Window__MUIM_AllocGadgetID(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_AllocGadgetID
*msg
)
3775 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3776 struct IDNode
*newnode
;
3778 newnode
= AllocPooled(data
->wd_MemoryPool
, sizeof(struct IDNode
));
3784 if (IsListEmpty((struct List
*)&data
->wd_IDList
))
3787 AddHead((struct List
*)&data
->wd_IDList
, (struct Node
*)&newnode
->node
);
3793 for (mn
= data
->wd_IDList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
3795 struct IDNode
*idn
= (struct IDNode
*)mn
;
3801 Insert((struct List
*)&data
->wd_IDList
, (struct Node
*)&newnode
->node
, (struct Node
*)mn
);
3808 /**************************************************************************
3810 **************************************************************************/
3811 IPTR
Window__MUIM_FreeGadgetID(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_FreeGadgetID
*msg
)
3813 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3816 for (mn
= data
->wd_IDList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
3818 struct IDNode
*idn
= (struct IDNode
*)mn
;
3819 if (msg
->gadgetid
== idn
->id
)
3821 Remove((struct Node
*)idn
);
3822 FreePooled(data
->wd_MemoryPool
, idn
, sizeof(struct IDNode
));
3831 /**************************************************************************
3832 MUIM_Window_GetMenuCheck
3833 **************************************************************************/
3834 IPTR
Window__MUIM_GetMenuCheck(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_GetMenuCheck
*msg
)
3837 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3839 Object
*strip
= data
->wd_ChildMenustrip
;
3840 if (!strip
) strip
= data
->wd_Menustrip
;
3841 if (!strip
) return 0;
3842 if (!(item
= (Object
*)DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
))) return 0;
3843 get(item
,MUIA_Menuitem_Checked
, &stat
);
3847 /**************************************************************************
3848 MUIM_Window_SetMenuCheck
3849 **************************************************************************/
3850 IPTR
Window__MUIM_SetMenuCheck(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_SetMenuCheck
*msg
)
3852 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3854 Object
*strip
= data
->wd_ChildMenustrip
;
3855 if (!strip
) strip
= data
->wd_Menustrip
;
3856 if (!strip
) return 0;
3857 if (!(item
= (Object
*)DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
))) return 0;
3858 set(item
,MUIA_Menuitem_Checked
,msg
->stat
);
3862 /**************************************************************************
3863 MUIM_Window_GetMenuState
3864 **************************************************************************/
3865 IPTR
Window__MUIM_GetMenuState(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_GetMenuState
*msg
)
3868 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3870 Object
*strip
= data
->wd_ChildMenustrip
;
3871 if (!strip
) strip
= data
->wd_Menustrip
;
3872 if (!strip
) return 0;
3873 if (!(item
= (Object
*)DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
))) return 0;
3874 get(item
,MUIA_Menuitem_Enabled
, &stat
);
3878 /**************************************************************************
3879 MUIM_Window_SetMenuState
3880 **************************************************************************/
3881 IPTR
Window__MUIM_SetMenuState(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_SetMenuState
*msg
)
3883 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3885 Object
*strip
= data
->wd_ChildMenustrip
;
3886 if (!strip
) strip
= data
->wd_Menustrip
;
3887 if (!strip
) return 0;
3888 if (!(item
= (Object
*)DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
))) return 0;
3889 set(item
,MUIA_Menuitem_Enabled
,msg
->stat
);
3893 /**************************************************************************
3894 MUIM_Window_DrawBackground
3895 **************************************************************************/
3896 IPTR
Window__MUIM_DrawBackground(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_DrawBackground
*msg
)
3898 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3899 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
3902 // D(bug("%d:zune_imspec_draw(%p) l=%d t=%d w=%d h=%d xo=%d yo=%d\n",
3903 // __LINE__, data->wd_Background, msg->left, msg->top, msg->width,
3904 // msg->height, msg->xoffset, msg->yoffset));
3905 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
3906 msg
->left
, msg
->top
, msg
->width
, msg
->height
,
3907 msg
->xoffset
, msg
->yoffset
, 0);
3911 /**************************************************************************
3913 **************************************************************************/
3914 IPTR
Window__MUIM_ToFront(struct IClass
*cl
, Object
*obj
, Msg msg
)
3916 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3917 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
3920 WindowToFront(data
->wd_RenderInfo
.mri_Window
);
3924 /**************************************************************************
3926 **************************************************************************/
3927 IPTR
Window__MUIM_ToBack(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 WindowToBack(data
->wd_RenderInfo
.mri_Window
);
3937 /**************************************************************************
3938 MUIM_Window_ScreenToBack
3939 **************************************************************************/
3940 IPTR
Window__MUIM_ScreenToBack(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 ScreenToBack(data
->wd_RenderInfo
.mri_Screen
);
3950 /**************************************************************************
3951 MUIM_Window_ScreenToFront
3952 **************************************************************************/
3953 IPTR
Window__MUIM_ScreenToFront(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 ScreenToFront(data
->wd_RenderInfo
.mri_Screen
);
3963 /**************************************************************************
3964 MUIM_Window_ActionIconify
3965 **************************************************************************/
3966 IPTR
Window__MUIM_ActionIconify(struct IClass
*cl
, Object
*obj
, Msg msg
)
3968 set(_app(obj
), MUIA_Application_Iconified
, TRUE
);
3974 /* Loads ENV: prefs, add a Window_ID chunk in the MUIW chunk, if no MUIW chunk
3975 * then create it at the same level as MUIC chunk, save prefs.
3976 * Do the same for ENVARC:
3977 * MUIW chunk layout:
3979 * 00 00 00 30 (chunk length for a single window, 0x30L big endian)
3982 * xx xx yy yy (X, Y)
3983 * ww ww hh hh (Width, Height)
3984 * ax ax ay ay (AltX, AltY)
3985 * aw aw ah ah (AltWidth, AltHeight)
3993 static void RememberWindowPosition(Object
*winobj
, ULONG id
)
3999 /* Loads ENV: prefs, remove our Window_ID chunk from the MUIW chunk, save prefs.
4000 * Do the same for ENVARC:
4001 * This function shouldnt really be in window.c, but rather in a file dealing
4002 * with prefs file stuff.
4004 static void ForgetWindowPosition(Object
*winobj
, ULONG id
)
4010 /**************************************************************************
4011 MUIM_Window_Snapshot
4012 **************************************************************************/
4013 IPTR
Window__MUIM_Snapshot(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_Snapshot
*msg
)
4015 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4016 struct windowpos winp
;
4018 winp
.id
= data
->wd_ID
;
4019 w
=data
->wd_RenderInfo
.mri_Window
;
4022 winp
.x1
= w
->LeftEdge
; winp
.y1
= w
->TopEdge
;
4023 winp
.w1
= w
->GZZWidth
; winp
.h1
= w
->GZZHeight
;
4024 winp
.x2
=0; winp
.x2
=0; winp
.w2
=0; winp
.h2
=0; //to do save alt dims
4026 set(_app(obj
),MUIA_Application_SetWinPos
,&winp
);
4030 RememberWindowPosition(obj
, data
->wd_ID
);
4032 ForgetWindowPosition(obj
, data
->wd_ID
);
4036 /**************************************************************************
4037 MUIM_Window_UpdateMenu
4038 **************************************************************************/
4039 IPTR
Window__MUIM_UpdateMenu(struct IClass
*cl
, Object
*obj
, Msg msg
)
4041 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4043 struct Menu
*menu
= NULL
;
4044 struct NewMenu
*newmenu
= NULL
;
4045 APTR visinfo
= NULL
;
4046 struct Window
*win
=NULL
;
4048 if (data
->wd_Menustrip
) // only open windows can have a menustrip
4050 if ((visinfo
= GetVisualInfoA(data
->wd_RenderInfo
.mri_Screen
, NULL
)))
4052 win
= data
->wd_RenderInfo
.mri_Window
;
4053 ClearMenuStrip(win
);
4056 FreeMenus(data
->wd_Menu
);
4057 data
->wd_Menu
= NULL
;
4060 get(data
->wd_Menustrip
, MUIA_Menuitem_NewMenu
, &newmenu
);
4063 if ((menu
= CreateMenusA(newmenu
, NULL
)))
4065 struct TagItem tags
[] =
4067 { GTMN_NewLookMenus
, TRUE
},
4068 { TAG_DONE
, (IPTR
)NULL
}
4070 LayoutMenusA(menu
, visinfo
, tags
);
4071 data
->wd_Menu
= menu
;
4072 SetMenuStrip(win
, menu
);
4075 FreeVisualInfo(visinfo
);
4083 BOOPSI_DISPATCHER(IPTR
, Window_Dispatcher
, cl
, obj
, msg
)
4085 switch (msg
->MethodID
)
4087 case OM_NEW
: return Window__OM_NEW(cl
, obj
, (struct opSet
*) msg
);
4088 case OM_DISPOSE
: return Window__OM_DISPOSE(cl
, obj
, msg
);
4089 case OM_SET
: return Window__OM_SET(cl
, obj
, (struct opSet
*)msg
);
4090 case OM_GET
: return Window__OM_GET(cl
, obj
, (struct opGet
*)msg
);
4091 case MUIM_FindUData
: return Window__MUIM_FindUData(cl
, obj
, (struct MUIP_FindUData
*)msg
);
4092 case MUIM_GetUData
: return Window__MUIM_GetUData(cl
, obj
, (struct MUIP_GetUData
*)msg
);
4093 case MUIM_SetUData
: return Window__MUIM_SetUData(cl
, obj
, (struct MUIP_SetUData
*)msg
);
4094 case MUIM_SetUDataOnce
: return Window__MUIM_SetUDataOnce(cl
, obj
, (struct MUIP_SetUDataOnce
*)msg
);
4095 case MUIM_Window_AddEventHandler
: return Window__MUIM_AddEventHandler(cl
, obj
, (APTR
)msg
);
4096 case MUIM_Window_RemEventHandler
: return Window__MUIM_RemEventHandler(cl
, obj
, (APTR
)msg
);
4097 case MUIM_ConnectParent
: return Window__MUIM_ConnectParent(cl
, obj
, (APTR
)msg
);
4098 case MUIM_DisconnectParent
: return Window__MUIM_DisconnectParent(cl
, obj
, (APTR
)msg
);
4099 case MUIM_Window_RecalcDisplay
: return Window__MUIM_RecalcDisplay(cl
, obj
, (APTR
)msg
);
4100 case MUIM_Window_Setup
: return Window__MUIM_Setup(cl
, obj
, (APTR
)msg
);
4101 case MUIM_Window_Cleanup
: return Window__MUIM_Cleanup(cl
, obj
, (APTR
)msg
);
4102 case MUIM_Window_AddControlCharHandler
: return Window__MUIM_AddControlCharHandler(cl
, obj
, (APTR
)msg
);
4103 case MUIM_Window_RemControlCharHandler
: return Window__MUIM_RemControlCharHandler(cl
, obj
, (APTR
)msg
);
4104 case MUIM_Window_DragObject
: return Window__MUIM_DragObject(cl
, obj
, (APTR
)msg
);
4105 case MUIM_Window_AllocGadgetID
: return Window__MUIM_AllocGadgetID(cl
, obj
, (APTR
)msg
);
4106 case MUIM_Window_FreeGadgetID
: return Window__MUIM_FreeGadgetID(cl
, obj
, (APTR
)msg
);
4107 case MUIM_Window_GetMenuCheck
: return Window__MUIM_GetMenuCheck(cl
, obj
, (APTR
)msg
);
4108 case MUIM_Window_SetMenuCheck
: return Window__MUIM_SetMenuCheck(cl
, obj
, (APTR
)msg
);
4109 case MUIM_Window_GetMenuState
: return Window__MUIM_GetMenuState(cl
, obj
, (APTR
)msg
);
4110 case MUIM_Window_SetMenuState
: return Window__MUIM_SetMenuState(cl
, obj
, (APTR
)msg
);
4111 case MUIM_Window_DrawBackground
: return Window__MUIM_DrawBackground(cl
, obj
, (APTR
)msg
);
4112 case MUIM_Window_ToFront
: return Window__MUIM_ToFront(cl
, obj
, (APTR
)msg
);
4113 case MUIM_Window_ToBack
: return Window__MUIM_ToBack(cl
, obj
, (APTR
)msg
);
4114 case MUIM_Window_ScreenToFront
: return Window__MUIM_ScreenToFront(cl
, obj
, (APTR
)msg
);
4115 case MUIM_Window_ScreenToBack
: return Window__MUIM_ScreenToBack(cl
, obj
, (APTR
)msg
);
4116 case MUIM_Window_ActionIconify
: return Window__MUIM_ActionIconify(cl
, obj
, (APTR
)msg
);
4117 case MUIM_Window_Snapshot
: return Window__MUIM_Snapshot(cl
, obj
, (APTR
)msg
);
4118 case MUIM_Window_UpdateMenu
: return Window__MUIM_UpdateMenu(cl
, obj
, (APTR
)msg
);
4121 return DoSuperMethodA(cl
, obj
, msg
);
4123 BOOPSI_DISPATCHER_END
4129 const struct __MUIBuiltinClass _MUI_Window_desc
= {
4132 sizeof(struct MUI_WindowData
),
4133 (void*)Window_Dispatcher