2 Copyright 1999, David Le Corfec.
3 Copyright 2002-2012, 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
135 WORD wd_SleepCount
; /* MUIA_Window_Sleep nests */
138 #ifndef WFLG_SIZEGADGET
140 #define WFLG_CLOSEGADGET (1<<0) /* has close gadget */
141 #define WFLG_SIZEGADGET (1<<1) /* has size gadget */
142 #define WFLG_BACKDROP (1<<2) /* is backdrop window */
143 #define WFLG_BORDERLESS (1<<3) /* has no borders */
144 #define WFLG_DEPTHGADGET (1<<4) /* has depth gadget */
145 #define WFLG_DRAGBAR (1<<5) /* is draggable */
146 #define WFLG_SIZEBRIGHT (1<<6) /* size gadget is in right border */
151 #define MUIWF_OPENED (1<<0) /* window currently opened */
152 #define MUIWF_HIDDEN (1<<1) /* window currently iconified */
153 #define MUIWF_ACTIVE (1<<2) /* window currently active */
154 #define MUIWF_RESIZING (1<<4) /* window currently resizing, for simple refresh */
155 #define MUIWF_DONTACTIVATE (1<<7) /* do not activate the window when opening */
156 #define MUIWF_USERIGHTSCROLLER (1<<8) /* window should have a right scroller */
157 #define MUIWF_USEBOTTOMSCROLLER (1<<9) /* window should have a bottom scroller */
158 #define MUIWF_ERASEAREA (1<<10) /* Erase area after a window resize */
159 #define MUIWF_ISAPPWINDOW (1<<11) /* Is an app window (user can drop icons on it) */
160 #define MUIWF_ISSUBWINDOW (1<<12) /* Dont get automatically disposed with app */
161 #define MUIWF_BUBBLEMODE (1<<13) /* Quick bubble mode. Bubbles appear quick when moving */
162 #define MUIWF_OPENONUNHIDE (1<<14) /* Open the window when unhiding */
163 #define MUIWF_SCREENLOCKED (1<<15) /* A pub screen was locked in SetupRenderInfo. Unlock it in CleanupRenderInfo! */
164 #define MUIWF_OBJECTGOACTIVESENT (1<<16) /* A MUIM_GoActive msg was sent to window's active object */
165 #define MUIWF_TOOLBOX (1<<17) /* Window should be opened as ToolBox */
167 #define BUBBLEHELP_TICKER_FIRST 10
168 #define BUBBLEHELP_TICKER_LATER 3
172 struct MUI_NotifyData mnd
;
173 struct MUI_WindowData mwd
;
176 #define muiWindowData(obj) (&(((struct __dummyXFC3__ *)(obj))->mwd))
178 static ULONG
DoHalfshineGun(ULONG a
, ULONG b
)
180 ULONG val
= ((((a
)>>24) + 3 * ((b
)>>24)) / 4);
181 val
= val
+ (val
<<8) + (val
<<16) + (val
<<24);
185 static ULONG
DoHalfshadowGun(ULONG a
, ULONG b
)
187 ULONG val
= ((((a
)>>24) + 5 * ((b
)>>24)) / 6);
188 val
= val
+ (val
<<8) + (val
<<16) + (val
<<24);
192 static Object
*CreateSysimage(struct DrawInfo
*dri
, ULONG which
)
194 return NewObject(NULL
, "sysiclass",
195 SYSIA_DrawInfo
, (IPTR
)dri
,
200 static void EnqueueByPriAndAddress(struct List
*list
, struct Node
*node
)
202 struct Node
*scannode
;
204 /* Sort by priority and by node address, so that a
205 "remove - modify - enqueue" sequence will re-add
206 the node at the same place in the list it was
209 ForeachNode(list
, scannode
)
211 if (((struct Node
*)node
)->ln_Pri
> scannode
->ln_Pri
)
213 if (((struct Node
*)node
)->ln_Pri
== scannode
->ln_Pri
)
215 if ((IPTR
)node
> (IPTR
)scannode
)
220 Insert(list
, (struct Node
*)node
, scannode
->ln_Pred
);
223 static BOOL
InitCustomFrames(Object
*obj
, struct MUI_RenderInfo
*mri
)
227 for (i
= 0; i
< 16; i
++)
229 mri
->mri_FrameImage
[i
] = NULL
;
232 mri
->mri_FrameImage
[0] = load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->customframe_config_1
, mri
->mri_Screen
);
233 mri
->mri_FrameImage
[1] = load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->customframe_config_2
, mri
->mri_Screen
);
234 mri
->mri_FrameImage
[2] = load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->customframe_config_3
, mri
->mri_Screen
);
235 mri
->mri_FrameImage
[3] = load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->customframe_config_4
, mri
->mri_Screen
);
236 mri
->mri_FrameImage
[4] = load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->customframe_config_5
, mri
->mri_Screen
);
237 mri
->mri_FrameImage
[5] = load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->customframe_config_6
, mri
->mri_Screen
);
238 mri
->mri_FrameImage
[6] = load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->customframe_config_7
, mri
->mri_Screen
);
239 mri
->mri_FrameImage
[7] = load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->customframe_config_8
, mri
->mri_Screen
);
240 mri
->mri_FrameImage
[8] = load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->customframe_config_9
, mri
->mri_Screen
);
241 mri
->mri_FrameImage
[9] = load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->customframe_config_10
, mri
->mri_Screen
);
242 mri
->mri_FrameImage
[10] = load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->customframe_config_11
, mri
->mri_Screen
);
243 mri
->mri_FrameImage
[11] = load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->customframe_config_12
, mri
->mri_Screen
);
244 mri
->mri_FrameImage
[12] = load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->customframe_config_13
, mri
->mri_Screen
);
245 mri
->mri_FrameImage
[13] = load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->customframe_config_14
, mri
->mri_Screen
);
246 mri
->mri_FrameImage
[14] = load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->customframe_config_15
, mri
->mri_Screen
);
247 mri
->mri_FrameImage
[15] = load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->customframe_config_16
, mri
->mri_Screen
);
252 static void DisposeCustomFrames(struct MUI_RenderInfo
*mri
)
256 for (i
= 0; i
< 16; i
++)
258 dispose_custom_frame(mri
->mri_FrameImage
[i
]);
260 mri
->mri_FrameImage
[i
] = NULL
;
264 static BOOL
SetupRenderInfo(Object
*obj
, struct MUI_WindowData
*data
, struct MUI_RenderInfo
*mri
)
266 ULONG rgbtable
[3 * 3];
271 /* TODO: Move this whole screen locking/opening stuff into the application class
272 * by creating methods for this purpose */
274 /* If no user screen has been specified try to open the application specifc screen */
275 if (!data
->wd_UserScreen
)
277 ULONG screenmodeid
= muiGlobalInfo(obj
)->mgi_Prefs
->screenmodeid
;
279 if (screenmodeid
!= ~0)
281 if (!muiGlobalInfo(obj
)->mgi_CustomScreen
)
283 muiGlobalInfo(obj
)->mgi_CustomScreen
= OpenScreenTags
286 SA_DisplayID
, screenmodeid
,
288 SA_FullPalette
, TRUE
,
289 SA_LikeWorkbench
,TRUE
,
292 /* It's fine if this fails as there is a back fall case below */
295 data
->wd_UserScreen
= muiGlobalInfo(obj
)->mgi_CustomScreen
;
298 if (data
->wd_UserScreen
)
300 mri
->mri_Screen
= data
->wd_UserScreen
;
304 if (data
->wd_UserPublicScreen
)
306 mri
->mri_Screen
= LockPubScreen(data
->wd_UserPublicScreen
);
308 else if (muiGlobalInfo(obj
)->mgi_Prefs
->publicscreen_name
&& muiGlobalInfo(obj
)->mgi_Prefs
->publicscreen_name
[0])
310 mri
->mri_Screen
= LockPubScreen(muiGlobalInfo(obj
)->mgi_Prefs
->publicscreen_name
);
311 // FIXME: open the public screen if necessary
314 if (mri
->mri_Screen
== NULL
)
316 mri
->mri_Screen
= LockPubScreen(NULL
);
317 if (mri
->mri_Screen
== NULL
)
323 // FIXME: is this the right place for this action?
324 if (mri
->mri_Screen
&& muiGlobalInfo(obj
)->mgi_Prefs
->publicscreen_pop_to_front
)
326 ScreenToFront(mri
->mri_Screen
);
329 data
->wd_Flags
|= MUIWF_SCREENLOCKED
;
332 if (!(mri
->mri_DrawInfo
= GetScreenDrawInfo(mri
->mri_Screen
)))
334 if (data
->wd_Flags
& MUIWF_SCREENLOCKED
)
336 UnlockPubScreen(NULL
,mri
->mri_Screen
);
337 data
->wd_Flags
&= ~MUIWF_SCREENLOCKED
;
342 if (!InitCustomFrames(obj
, mri
))
344 if (data
->wd_Flags
& MUIWF_SCREENLOCKED
)
346 UnlockPubScreen(NULL
,mri
->mri_Screen
);
347 data
->wd_Flags
&= ~MUIWF_SCREENLOCKED
;
352 mri
->mri_Colormap
= mri
->mri_Screen
->ViewPort
.ColorMap
;
353 mri
->mri_ScreenWidth
= mri
->mri_Screen
->Width
;
354 mri
->mri_ScreenHeight
= mri
->mri_Screen
->Height
;
356 if (mri
->mri_ScreenWidth
/ mri
->mri_ScreenHeight
< 2)
358 mri
->mri_Flags
|= MUIMRI_THINFRAMES
;
361 if (GetBitMapAttr(mri
->mri_Screen
->RastPort
.BitMap
, BMA_DEPTH
) >= 15)
363 mri
->mri_Flags
|= MUIMRI_TRUECOLOR
;
366 mri
->mri_PensStorage
[MPEN_SHINE
] = mri
->mri_DrawInfo
->dri_Pens
[SHINEPEN
];
367 mri
->mri_PensStorage
[MPEN_BACKGROUND
] = mri
->mri_DrawInfo
->dri_Pens
[BACKGROUNDPEN
];
368 mri
->mri_PensStorage
[MPEN_SHADOW
] = mri
->mri_DrawInfo
->dri_Pens
[SHADOWPEN
];
369 mri
->mri_PensStorage
[MPEN_TEXT
] = mri
->mri_DrawInfo
->dri_Pens
[TEXTPEN
];
370 mri
->mri_PensStorage
[MPEN_FILL
] = mri
->mri_DrawInfo
->dri_Pens
[FILLPEN
];
372 GetRGB32(mri
->mri_Colormap
, mri
->mri_DrawInfo
->dri_Pens
[SHINEPEN
], 1, rgbtable
);
373 GetRGB32(mri
->mri_Colormap
, mri
->mri_DrawInfo
->dri_Pens
[BACKGROUNDPEN
], 1, rgbtable
+3);
374 GetRGB32(mri
->mri_Colormap
, mri
->mri_DrawInfo
->dri_Pens
[SHADOWPEN
], 1, rgbtable
+6);
376 mri
->mri_PensStorage
[MPEN_HALFSHINE
] = ObtainBestPenA
379 DoHalfshineGun(rgbtable
[0], rgbtable
[3]),
380 DoHalfshineGun(rgbtable
[1], rgbtable
[4]),
381 DoHalfshineGun(rgbtable
[2], rgbtable
[5]), NULL
384 mri
->mri_PensStorage
[MPEN_HALFSHADOW
] = ObtainBestPenA
387 DoHalfshadowGun(rgbtable
[6], rgbtable
[3]),
388 DoHalfshadowGun(rgbtable
[7], rgbtable
[4]),
389 DoHalfshadowGun(rgbtable
[8], rgbtable
[5]), NULL
392 /* I'm really not sure that MUI does this for MPEN_MARK, but it seems mostly acceptable -dlc */
393 mri
->mri_PensStorage
[MPEN_MARK
] = ObtainBestPenA
395 mri
->mri_Colormap
, 0xf4f4f4f4, 0xb5b5b5b5, 0x8b8b8b8b, NULL
398 mri
->mri_Pens
= mri
->mri_PensStorage
;
400 for (i
= 0; i
< -MUIV_Font_NegCount
; i
++)
402 mri
->mri_Fonts
[i
] = NULL
;
405 if (data
->wd_Flags
& MUIWF_USEBOTTOMSCROLLER
)
407 mri
->mri_LeftImage
= CreateSysimage(mri
->mri_DrawInfo
, LEFTIMAGE
);
408 mri
->mri_RightImage
= CreateSysimage(mri
->mri_DrawInfo
, RIGHTIMAGE
);
412 mri
->mri_LeftImage
= mri
->mri_RightImage
= NULL
;
415 if (data
->wd_Flags
& MUIWF_USERIGHTSCROLLER
)
417 mri
->mri_UpImage
= CreateSysimage(mri
->mri_DrawInfo
, UPIMAGE
);
418 mri
->mri_DownImage
= CreateSysimage(mri
->mri_DrawInfo
, DOWNIMAGE
);
422 mri
->mri_UpImage
= mri
->mri_DownImage
= NULL
;
425 if ((data
->wd_Flags
& MUIWF_USEBOTTOMSCROLLER
) ||
426 (data
->wd_Flags
& MUIWF_USERIGHTSCROLLER
))
427 mri
->mri_SizeImage
= CreateSysimage(mri
->mri_DrawInfo
, SIZEIMAGE
);
429 mri
->mri_SizeImage
= NULL
;
431 if (data
->wd_CrtFlags
& WFLG_BORDERLESS
)
433 /* Infact borderless windows could also have borders (if they have a window title e.g. but
434 since they look ugly anywhy we ignore it for now */
435 mri
->mri_BorderLeft
= 0;
436 mri
->mri_BorderRight
= 0;
437 mri
->mri_BorderTop
= 0;
438 mri
->mri_BorderBottom
= 0;
442 mri
->mri_BorderLeft
= mri
->mri_Screen
->WBorLeft
;
443 mri
->mri_BorderTop
= mri
->mri_Screen
->WBorTop
+ mri
->mri_Screen
->Font
->ta_YSize
+ 1;
447 SYSIA_DrawInfo
, (IPTR
)mri
->mri_DrawInfo
,
448 SYSIA_Which
, SIZEIMAGE
,
453 GetAttr(IA_Height
,temp_obj
,&val
);
454 DisposeObject(temp_obj
);
455 mri
->mri_BorderBottom
= val
;
458 mri
->mri_BorderBottom
= mri
->mri_Screen
->WBorBottom
;
464 static void CleanupRenderInfo(Object
*obj
, struct MUI_WindowData
*data
, struct MUI_RenderInfo
*mri
)
468 DisposeCustomFrames(mri
);
470 if (mri
->mri_LeftImage
) {DisposeObject(mri
->mri_LeftImage
);mri
->mri_LeftImage
=NULL
;};
471 if (mri
->mri_RightImage
){DisposeObject(mri
->mri_RightImage
);mri
->mri_RightImage
=NULL
;};
472 if (mri
->mri_UpImage
) {DisposeObject(mri
->mri_UpImage
);mri
->mri_UpImage
=NULL
;};
473 if (mri
->mri_DownImage
) {DisposeObject(mri
->mri_DownImage
);mri
->mri_DownImage
=NULL
;};
474 if (mri
->mri_SizeImage
) {DisposeObject(mri
->mri_SizeImage
);mri
->mri_SizeImage
=NULL
;};
476 /* bug("CleanupRenderInfo\n"); */
477 for (i
= 0; i
< -MUIV_Font_NegCount
; i
++)
479 if (mri
->mri_Fonts
[i
])
481 /* bug("CleanupRenderInfo: closing font %p (%s/%d)\n", */
482 /* mri->mri_Fonts[i], mri->mri_Fonts[i]->tf_Message.mn_Node.ln_Name, */
483 /* mri->mri_Fonts[i]->tf_YSize); */
484 CloseFont(mri
->mri_Fonts
[i
]);
485 mri
->mri_Fonts
[i
] = NULL
;
488 ReleasePen(mri
->mri_Colormap
, mri
->mri_PensStorage
[MPEN_MARK
]);
489 ReleasePen(mri
->mri_Colormap
, mri
->mri_PensStorage
[MPEN_HALFSHADOW
]);
490 ReleasePen(mri
->mri_Colormap
, mri
->mri_PensStorage
[MPEN_HALFSHINE
]);
491 FreeScreenDrawInfo(mri
->mri_Screen
, mri
->mri_DrawInfo
);
492 mri
->mri_DrawInfo
= NULL
;
494 /* If a custom screen has been opened by zune, close it as soon as
495 * zero windows are opened. See above for comments about refactorization. */
496 if (muiGlobalInfo(obj
)->mgi_CustomScreen
)
498 BOOL screenclose
= TRUE
;
499 Object
*_app
= _app(obj
);
502 struct List
*store
= NULL
;
503 get(_app
, MUIA_Application_WindowList
, &store
);
506 if (!IsListEmpty(store
)) screenclose
= FALSE
;
511 /* If the window's user screen really was the custom screen, clear the reference */
512 if (data
->wd_UserScreen
== muiGlobalInfo(obj
)->mgi_CustomScreen
)
513 data
->wd_UserScreen
= NULL
;
515 CloseScreen(muiGlobalInfo(obj
)->mgi_CustomScreen
);
516 muiGlobalInfo(obj
)->mgi_CustomScreen
= NULL
;
521 if (data
->wd_Flags
& MUIWF_SCREENLOCKED
)
523 UnlockPubScreen(NULL
, mri
->mri_Screen
);
524 data
->wd_Flags
&= ~MUIWF_SCREENLOCKED
;
526 mri
->mri_Screen
= NULL
;
529 static void ShowRenderInfo(struct MUI_RenderInfo
*mri
)
531 if (mri
->mri_BufferBM
)
533 mri
->mri_RastPort
= &mri
->mri_BufferRP
;
537 mri
->mri_RastPort
= mri
->mri_Window
->RPort
;
541 static void HideRenderInfo(struct MUI_RenderInfo
*mri
)
543 mri
->mri_RastPort
= NULL
;
546 static ULONG
GetDefaultEvents (void)
548 return IDCMP_NEWSIZE
| IDCMP_REFRESHWINDOW
549 | IDCMP_MOUSEBUTTONS
| IDCMP_MOUSEMOVE
| IDCMP_MENUPICK
550 | IDCMP_CLOSEWINDOW
| IDCMP_RAWKEY
| IDCMP_INTUITICKS
551 | IDCMP_ACTIVEWINDOW
| IDCMP_INACTIVEWINDOW
| IDCMP_GADGETUP
;
554 static void ChangeEvents (struct MUI_WindowData
*data
, ULONG new_events
)
557 struct MUI_EventHandlerNode
*ehn
;
558 ULONG old_events
= data
->wd_Events
;
560 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
562 ehn
= (struct MUI_EventHandlerNode
*)mn
;
563 new_events
|= ehn
->ehn_Events
;
566 /* sba: kill the IDCMP_VANILLAKEY flag. MUI doesn't do this but programs
567 ** which use this will behave different if they request for this flag
570 new_events
&= ~IDCMP_VANILLAKEY
;
572 data
->wd_Events
= new_events
;
573 if ((old_events
!= new_events
) && (data
->wd_Flags
& MUIWF_OPENED
))
575 ModifyIDCMP(data
->wd_RenderInfo
.mri_Window
, new_events
);
579 static void CalcWindowPosition(Object
*obj
, struct MUI_WindowData
*data
);
580 static void CreateWindowScrollbars(Object
*obj
, struct MUI_WindowData
*data
);
581 static void CalcAltDimensions(Object
*obj
, struct MUI_WindowData
*data
);
582 static void UndisplayWindow(Object
*obj
, struct MUI_WindowData
*data
);
583 static struct ObjNode
*FindObjNode(struct MinList
*list
, Object
*obj
);
585 static BOOL
DisplayWindow(Object
*obj
, struct MUI_WindowData
*data
)
588 ULONG flags
= data
->wd_CrtFlags
;
590 ULONG backfill
, buttons
;
592 struct Menu
*menu
= NULL
;
593 struct NewMenu
*newmenu
= NULL
;
598 if (!(data
->wd_Flags
& MUIWF_DONTACTIVATE
))
600 flags
|= WFLG_ACTIVATE
;
603 /* Toolboxes are handled differently on AmigaOS */
605 if (data
->wd_Flags
& MUIWF_TOOLBOX
)
606 flags
|= WFLG_TOOLBOX
;
611 data
->wd_MinMax
.MinHeight
== data
->wd_MinMax
.MaxHeight
612 && data
->wd_MinMax
.MinWidth
== data
->wd_MinMax
.MaxWidth
614 flags
&= ~WFLG_SIZEGADGET
;
616 if (!(flags
& WFLG_SIZEBRIGHT
))
617 flags
|= WFLG_SIZEBBOTTOM
;
619 CalcWindowPosition(obj
, data
);
621 if ((visinfo
= GetVisualInfoA(data
->wd_RenderInfo
.mri_Screen
,NULL
)))
623 if (data
->wd_Menustrip
)
625 get(data
->wd_Menustrip
,MUIA_Menuitem_NewMenu
,&newmenu
);
628 if ((menu
= CreateMenusA(newmenu
,NULL
)))
630 struct TagItem tags
[] =
632 { GTMN_NewLookMenus
, TRUE
},
633 { TAG_DONE
, (IPTR
)NULL
}
635 LayoutMenusA(menu
, visinfo
, tags
);
639 FreeVisualInfo(visinfo
);
642 CreateWindowScrollbars(obj
, data
);
643 CalcAltDimensions(obj
, data
);
644 altdims
= data
->wd_AltDim
;
645 /* hack to account for border size, as we only know the innersize and must give
648 altdims
.Width
+= data
->wd_RenderInfo
.mri_Screen
->WBorLeft
+ data
->wd_RenderInfo
.mri_Screen
->WBorRight
;
649 altdims
.Height
+= data
->wd_RenderInfo
.mri_Screen
->WBorTop
+ data
->wd_RenderInfo
.mri_Screen
->WBorBottom
+
650 data
->wd_RenderInfo
.mri_DrawInfo
->dri_Font
->tf_YSize
+ 1;
652 if (muiGlobalInfo(obj
)->mgi_Prefs
->window_redraw
== WINDOW_REDRAW_WITHOUT_CLEAR
)
653 backfill
= WA_BackFill
;
655 backfill
= TAG_IGNORE
;
657 if (muiGlobalInfo(obj
)->mgi_Prefs
->window_refresh
== WINDOW_REFRESH_SMART
)
658 flags
&= ~WFLG_SIMPLE_REFRESH
;
659 set(_app(obj
),MUIA_Application_SearchWinId
,data
->wd_ID
);
660 struct windowpos
*winp
=0;
661 get(_app(obj
),MUIA_Application_GetWinPos
,&winp
);
664 if (data
->wd_RenderInfo
.mri_ScreenWidth
> (data
->wd_X
+ data
->wd_Width
))
667 data
->wd_Width
=winp
->w1
;
669 if (data
->wd_RenderInfo
.mri_ScreenHeight
> (data
->wd_Y
+ data
->wd_Height
))
672 data
->wd_Height
=winp
->h1
;
676 gadgets
= (data
->wd_VertProp
!= NULL
) ? data
->wd_VertProp
: data
->wd_HorizProp
;
677 buttons
= muiGlobalInfo(obj
)->mgi_Prefs
->window_buttons
;
683 WA_Left
, (IPTR
) data
->wd_X
,
684 WA_Top
, (IPTR
) data
->wd_Y
,
685 WA_Flags
, (IPTR
) flags
,
688 TAG_IGNORE
, (IPTR
) data
->wd_Title
,
689 data
->wd_ScreenTitle
?
691 TAG_IGNORE
, (IPTR
) data
->wd_ScreenTitle
,
692 WA_CustomScreen
, (IPTR
) data
->wd_RenderInfo
.mri_Screen
,
693 WA_InnerWidth
, (IPTR
) data
->wd_Width
,
694 WA_InnerHeight
, (IPTR
) data
->wd_Height
,
695 WA_AutoAdjust
, (IPTR
) TRUE
,
696 WA_NewLookMenus
, (IPTR
) TRUE
,
697 /* AmigaOS v4 extension */
699 WA_ToolBox
, (IPTR
) !!(data
->wd_Flags
& MUIWF_TOOLBOX
),
701 /* MorphOS extensions */
702 #ifdef WA_ExtraGadget_MUI
703 WA_ExtraGadget_MUI
, (IPTR
) ((buttons
& MUIV_Window_Button_MUI
) != 0) ? TRUE
: FALSE
,
704 WA_ExtraGadget_PopUp
, (IPTR
) ((buttons
& MUIV_Window_Button_Popup
) != 0) ? TRUE
: FALSE
,
705 WA_ExtraGadget_Snapshot
,(IPTR
) ((buttons
& MUIV_Window_Button_Snapshot
) != 0) ? TRUE
: FALSE
,
706 WA_ExtraGadget_Iconify
, (IPTR
) ((buttons
& MUIV_Window_Button_Iconify
) != 0) ? TRUE
: FALSE
,
710 TAG_IGNORE
, (IPTR
) TRUE
,
711 WA_Gadgets
, (IPTR
) gadgets
,
712 data
->wd_ZoomGadget
?
714 TAG_IGNORE
, (IPTR
) &altdims
,
715 backfill
, (IPTR
) LAYERS_NOBACKFILL
,
722 int hborders
= win
->BorderLeft
+ win
->BorderRight
;
723 int vborders
= win
->BorderTop
+ win
->BorderBottom
;
725 /* recalc window size (which will hopefully equal our requested size) */
726 data
->wd_Width
= win
->GZZWidth
;
727 data
->wd_Height
= win
->GZZHeight
;
729 /* set window limits according to window contents */
732 win
, data
->wd_MinMax
.MinWidth
+ hborders
,
733 data
->wd_MinMax
.MinHeight
+ vborders
,
734 data
->wd_MinMax
.MaxWidth
+ hborders
,
735 data
->wd_MinMax
.MaxHeight
+ vborders
738 win
->UserData
= (BYTE
*)data
->wd_RenderInfo
.mri_WindowObject
;
739 win
->UserPort
= muiGlobalInfo(obj
)->mgi_WindowsPort
; /* Same port for all windows */
740 ModifyIDCMP(win
, data
->wd_Events
);
742 data
->wd_RenderInfo
.mri_Window
= win
;
743 data
->wd_RenderInfo
.mri_VertProp
= data
->wd_VertProp
;
744 data
->wd_RenderInfo
.mri_HorizProp
= data
->wd_HorizProp
;
745 SetDrMd(win
->RPort
,JAM1
); //text is draw wrong in toolbarclass if not set
749 data
->wd_Menu
= menu
;
750 SetMenuStrip(win
,menu
);
753 if (flags
& WFLG_ACTIVATE
)
755 data
->wd_Flags
|= MUIWF_ACTIVE
;
761 if (menu
) FreeMenus(menu
);
762 UndisplayWindow(obj
, data
);
768 static void UndisplayWindow(Object
*obj
, struct MUI_WindowData
*data
)
770 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
771 if ((data
->wd_XStore
>= 0) && (data
->wd_YStore
>= 0))
773 DoMethod(obj
,MUIM_Window_Snapshot
,0);
776 data
->wd_RenderInfo
.mri_Window
= NULL
;
777 data
->wd_RenderInfo
.mri_VertProp
= NULL
;
778 data
->wd_RenderInfo
.mri_HorizProp
= NULL
;
780 data
->wd_Flags
&= ~MUIWF_ACTIVE
;
784 /* store position and size */
785 if (data
->wd_XStore
>=0)
786 data
->wd_X
= win
->LeftEdge
;
788 data
->wd_X
= data
->wd_XStore
;
789 if (data
->wd_YStore
>=0)
790 data
->wd_Y
= win
->TopEdge
;
792 data
->wd_Y
= data
->wd_YStore
;
793 data
->wd_Width
= win
->GZZWidth
;
794 data
->wd_Height
= win
->GZZHeight
;
799 FreeMenus(data
->wd_Menu
);
800 data
->wd_Menu
= NULL
;
805 struct IntuiMessage
*msg
, *succ
;
807 /* remove all messages pending for this window */
811 msg
= (struct IntuiMessage
*)win
->UserPort
->mp_MsgList
.lh_Head
;
812 (succ
= (struct IntuiMessage
*)msg
->ExecMessage
.mn_Node
.ln_Succ
);
816 if (msg
->IDCMPWindow
== win
)
818 Remove((struct Node
*)msg
);
819 ReplyMsg((struct Message
*)msg
);
822 win
->UserPort
= NULL
;
827 /* D(bug("before CloseWindow\n")); */
829 /* D(bug("after CloseWindow\n")); */
832 #define DISPOSEGADGET(x) \
835 DoMethod(obj, MUIM_Window_FreeGadgetID, ((struct Gadget*)x)->GadgetID);\
840 DISPOSEGADGET(data
->wd_VertProp
);
841 DISPOSEGADGET(data
->wd_UpButton
);
842 DISPOSEGADGET(data
->wd_DownButton
);
843 DISPOSEGADGET(data
->wd_HorizProp
);
844 DISPOSEGADGET(data
->wd_LeftButton
);
845 DISPOSEGADGET(data
->wd_RightButton
);
850 /* Initialize data->wd_X and data->wd_Y for DisplayWindow */
851 /* FIXME 20030817: needs some fixing, seems not fully implemented */
852 static void CalcWindowPosition(Object
*obj
, struct MUI_WindowData
*data
)
854 data
->wd_XStore
= data
->wd_X
;
855 data
->wd_YStore
= data
->wd_Y
;
856 if (NULL
== data
->wd_RefWindow
)
858 /* The following calculations are not very correct, the size and dragbar
859 ** are ignored also the current overscan view */
860 if (data
->wd_X
== MUIV_Window_LeftEdge_Centered
)
862 data
->wd_X
= (data
->wd_RenderInfo
.mri_Screen
->ViewPort
.DWidth
- data
->wd_Width
)/2
863 - data
->wd_RenderInfo
.mri_Screen
->LeftEdge
;
865 else if (data
->wd_X
== MUIV_Window_LeftEdge_Moused
)
867 data
->wd_X
= data
->wd_RenderInfo
.mri_Screen
->MouseX
;
870 if (data
->wd_Y
== MUIV_Window_TopEdge_Centered
)
872 data
->wd_Y
= (data
->wd_RenderInfo
.mri_Screen
->ViewPort
.DHeight
- data
->wd_Height
)/2
873 - data
->wd_RenderInfo
.mri_Screen
->TopEdge
;
875 else if (data
->wd_Y
== MUIV_Window_TopEdge_Moused
)
877 data
->wd_Y
= data
->wd_RenderInfo
.mri_Screen
->MouseY
;
879 else if (data
->wd_Y
<= MUIV_Window_TopEdge_Delta(0))
881 data
->wd_Y
= data
->wd_RenderInfo
.mri_Screen
->BarHeight
+ 1
882 + MUIV_Window_TopEdge_Delta(0) - data
->wd_Y
;
890 get(data
->wd_RefWindow
, MUIA_Window_Width
, &w
);
891 get(data
->wd_RefWindow
, MUIA_Window_LeftEdge
, &x
);
893 if (data
->wd_X
== MUIV_Window_LeftEdge_Centered
)
895 data
->wd_X
= x
+ (w
- data
->wd_Width
)/2;
902 get(data
->wd_RefWindow
, MUIA_Window_Height
, &h
);
903 get(data
->wd_RefWindow
, MUIA_Window_TopEdge
, &y
);
905 if (data
->wd_Y
== MUIV_Window_TopEdge_Centered
)
907 /* D(bug("y=%ld, h=%ld, wdh=%ld\n", y, h, data->wd_Height)); */
908 data
->wd_Y
= y
+ (h
- data
->wd_Height
)/2;
910 else if (data
->wd_Y
<= MUIV_Window_TopEdge_Delta(0))
912 /* ??? surely incorrect implementation */
913 data
->wd_Y
= y
+ 1 + MUIV_Window_TopEdge_Delta(0) - data
->wd_Y
;
922 /* Initialize data->wd_AltDim for DisplayWindow */
923 static void CalcAltDimensions(Object
*obj
, struct MUI_WindowData
*data
)
925 /* Calculate alternate (zoomed) dimensions.
927 if (data
->wd_AltDim
.Top
== MUIV_Window_AltTopEdge_NoChange
)
928 data
->wd_AltDim
.Top
= ~0;
929 else if (data
->wd_AltDim
.Top
== MUIV_Window_AltTopEdge_Centered
)
930 data
->wd_AltDim
.Top
= (data
->wd_RenderInfo
.mri_Screen
->Height
- data
->wd_Height
)/2;
931 else if (data
->wd_AltDim
.Top
== MUIV_Window_AltTopEdge_Moused
)
932 /* ? */ data
->wd_AltDim
.Top
= ~0;
934 if (data
->wd_AltDim
.Left
== MUIV_Window_AltLeftEdge_NoChange
)
935 data
->wd_AltDim
.Left
= ~0;
936 else if (data
->wd_AltDim
.Left
== MUIV_Window_AltLeftEdge_Centered
)
937 data
->wd_AltDim
.Left
= (data
->wd_RenderInfo
.mri_Screen
->Width
- data
->wd_Width
)/2;
938 else if (data
->wd_AltDim
.Left
== MUIV_Window_AltLeftEdge_Moused
)
939 /* ? */ data
->wd_AltDim
.Left
= ~0;
945 MUIV_Window_AltWidth_MinMax(100),
946 data
->wd_AltDim
.Width
,
947 MUIV_Window_AltWidth_MinMax(0)
951 data
->wd_AltDim
.Width
= data
->wd_MinMax
.MinWidth
952 - data
->wd_AltDim
.Width
953 * (data
->wd_MinMax
.MaxWidth
- data
->wd_MinMax
.MinWidth
);
959 MUIV_Window_AltWidth_Screen(100),
960 data
->wd_AltDim
.Width
,
961 MUIV_Window_AltWidth_Screen(0)
965 data
->wd_AltDim
.Width
= data
->wd_RenderInfo
.mri_ScreenWidth
966 * (- (data
->wd_AltDim
.Width
+ 200)) / 100;
972 MUIV_Window_AltWidth_Visible(100),
973 data
->wd_AltDim
.Width
,
974 MUIV_Window_AltWidth_Visible(0)
978 data
->wd_AltDim
.Width
= data
->wd_RenderInfo
.mri_ScreenWidth
979 * (- (data
->wd_AltDim
.Width
+ 100)) / 100;
986 MUIV_Window_AltHeight_MinMax(100),
987 data
->wd_AltDim
.Height
,
988 MUIV_Window_AltHeight_MinMax(0)
992 data
->wd_AltDim
.Height
= data
->wd_MinMax
.MinHeight
993 - data
->wd_AltDim
.Height
994 * (data
->wd_MinMax
.MaxHeight
- data
->wd_MinMax
.MinHeight
);
1000 MUIV_Window_AltHeight_Screen(100),
1001 data
->wd_AltDim
.Height
,
1002 MUIV_Window_AltHeight_Screen(0)
1006 data
->wd_AltDim
.Height
= data
->wd_RenderInfo
.mri_ScreenHeight
1007 * (- (data
->wd_AltDim
.Height
+ 200)) / 100;
1013 MUIV_Window_AltHeight_Visible(100),
1014 data
->wd_AltDim
.Height
,
1015 MUIV_Window_AltHeight_Visible(0)
1019 data
->wd_AltDim
.Height
= data
->wd_RenderInfo
.mri_ScreenHeight
1020 * (- (data
->wd_AltDim
.Height
+ 100)) / 100;
1023 data
->wd_AltDim
.Width
= CLAMP
1025 data
->wd_AltDim
.Width
, data
->wd_MinMax
.MinWidth
,
1026 data
->wd_MinMax
.MaxWidth
1028 data
->wd_AltDim
.Height
= CLAMP
1030 data
->wd_AltDim
.Height
, data
->wd_MinMax
.MinHeight
,
1031 data
->wd_MinMax
.MaxHeight
1036 /* Create horiz/vert window scrollbars for DisplayWindow */
1037 static void CreateWindowScrollbars(Object
*obj
, struct MUI_WindowData
*data
)
1039 struct MUI_RenderInfo
*mri
= &data
->wd_RenderInfo
;
1040 Object
*firstgad
= NULL
;
1041 Object
*prevgad
= NULL
;
1044 /* Create the right border scrollers now if requested */
1045 if (data
->wd_Flags
& MUIWF_USERIGHTSCROLLER
)
1049 voffset
= IM(mri
->mri_DownImage
)->Width
/ 4;
1051 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1052 firstgad
= prevgad
= data
->wd_VertProp
= NewObject
1056 GA_RelRight
, 1 - (IM(mri
->mri_UpImage
)->Width
- voffset
),
1057 GA_Top
, mri
->mri_BorderTop
+ 2,
1058 GA_Width
, IM(mri
->mri_UpImage
)->Width
- voffset
* 2,
1059 GA_RelHeight
, - (mri
->mri_BorderTop
+ 2)
1060 - IM(mri
->mri_UpImage
)->Height
1061 - IM(mri
->mri_DownImage
)->Height
1062 - IM(mri
->mri_SizeImage
)->Height
- 2,
1063 GA_RightBorder
, TRUE
,
1065 PGA_Borderless
, TRUE
,
1067 PGA_Freedom
, FREEVERT
,
1071 ICA_TARGET
, ICTARGET_IDCMP
,
1075 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1076 prevgad
= data
->wd_UpButton
= NewObject
1078 NULL
, "buttongclass",
1080 GA_Image
, (IPTR
)mri
->mri_UpImage
,
1081 GA_RelRight
, 1 - IM(mri
->mri_UpImage
)->Width
,
1082 GA_RelBottom
, 1 - IM(mri
->mri_UpImage
)->Height
1083 - IM(mri
->mri_DownImage
)->Height
1084 - IM(mri
->mri_SizeImage
)->Height
,
1085 GA_RightBorder
, TRUE
,
1086 GA_Previous
, (IPTR
)prevgad
,
1088 ICA_TARGET
, ICTARGET_IDCMP
,
1092 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1093 prevgad
= data
->wd_DownButton
= NewObject
1095 NULL
, "buttongclass",
1097 GA_Image
, (IPTR
)mri
->mri_DownImage
,
1098 GA_RelRight
, 1 - IM(mri
->mri_DownImage
)->Width
,
1099 GA_RelBottom
, 1 - IM(mri
->mri_DownImage
)->Height
1100 - IM(mri
->mri_SizeImage
)->Height
,
1101 GA_RightBorder
, TRUE
,
1102 GA_Previous
, (IPTR
)prevgad
,
1104 ICA_TARGET
, ICTARGET_IDCMP
,
1107 } // if (data->wd_Flags & MUIWF_USERIGHTSCROLLER)
1109 /* Create the bottom border scrollers now if requested */
1110 if (data
->wd_Flags
& MUIWF_USEBOTTOMSCROLLER
)
1114 hoffset
= IM(mri
->mri_RightImage
)->Height
/ 4;
1116 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1117 prevgad
= data
->wd_HorizProp
= NewObject
1121 GA_RelBottom
, 1 - (IM(mri
->mri_LeftImage
)->Height
- hoffset
),
1122 GA_Left
, mri
->mri_BorderLeft
,
1123 GA_Height
, IM(mri
->mri_LeftImage
)->Height
1125 GA_RelWidth
, - (mri
->mri_BorderLeft
)
1126 - IM(mri
->mri_LeftImage
)->Width
1127 - IM(mri
->mri_RightImage
)->Width
1128 - IM(mri
->mri_SizeImage
)->Width
1130 GA_BottomBorder
, TRUE
,
1132 prevgad
? GA_Previous
: TAG_IGNORE
, (IPTR
)prevgad
,
1133 PGA_Borderless
, TRUE
,
1135 PGA_Freedom
, FREEHORIZ
,
1139 ICA_TARGET
, ICTARGET_IDCMP
,
1143 if (!firstgad
) firstgad
= prevgad
;
1145 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1146 prevgad
= data
->wd_LeftButton
= NewObject
1148 NULL
, "buttongclass",
1150 GA_Image
, (IPTR
)mri
->mri_LeftImage
,
1151 GA_RelRight
, 1 - IM(mri
->mri_LeftImage
)->Width
1152 - IM(mri
->mri_RightImage
)->Width
1153 - IM(mri
->mri_SizeImage
)->Width
,
1154 GA_RelBottom
, 1 - IM(mri
->mri_LeftImage
)->Height
,
1155 GA_BottomBorder
, TRUE
,
1156 GA_Previous
, (IPTR
)prevgad
,
1158 ICA_TARGET
, ICTARGET_IDCMP
,
1162 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1163 prevgad
= data
->wd_RightButton
= NewObject
1165 NULL
, "buttongclass",
1167 GA_Image
, (IPTR
)mri
->mri_RightImage
,
1168 GA_RelRight
, 1 - IM(mri
->mri_RightImage
)->Width
1169 - IM(mri
->mri_SizeImage
)->Width
,
1170 GA_RelBottom
, 1 - IM(mri
->mri_RightImage
)->Height
,
1171 GA_BottomBorder
, TRUE
,
1172 GA_Previous
, (IPTR
)prevgad
,
1174 ICA_TARGET
, ICTARGET_IDCMP
,
1176 } // if (data->wd_Flags & MUIWF_USEBOTTOMSCROLLER)
1179 /* return FALSE only if no resize (dx=dy=0) occured */
1180 static BOOL
WindowResize (struct MUI_WindowData
*data
)
1182 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
1183 int hborders
= win
->BorderLeft
+ win
->BorderRight
;
1184 int vborders
= win
->BorderTop
+ win
->BorderBottom
;
1185 WORD dx
= data
->wd_Width
- win
->Width
+ hborders
;
1186 WORD dy
= data
->wd_Height
- win
->Height
+ vborders
;
1188 /* Temporarily disable window limits to let SizeWindow below work
1189 regardless of the previous limits */
1190 WindowLimits(win
, 1, 1, -1, -1);
1191 /* D(bug("_zune_window_resize : dx=%d, dy=%d\n", dx, dy)); */
1192 SizeWindow(win
, dx
, dy
);
1194 /* Set new window limits */
1197 win
, data
->wd_MinMax
.MinWidth
+ hborders
,
1198 data
->wd_MinMax
.MinHeight
+ vborders
,
1199 data
->wd_MinMax
.MaxWidth
+ hborders
,
1200 data
->wd_MinMax
.MaxHeight
+ vborders
1206 static void KillHelpBubble(struct MUI_WindowData
*data
, Object
*obj
, BOOL kill_bubblemode
)
1208 if (data
->wd_HelpObject
)
1210 DoMethod(data
->wd_HelpObject
, MUIM_DeleteBubble
, (IPTR
)data
->wd_HelpBubble
);
1211 data
->wd_HelpObject
= NULL
;
1212 data
->wd_HelpBubble
= NULL
;
1215 if (kill_bubblemode
) data
->wd_Flags
&= ~MUIWF_BUBBLEMODE
;
1217 if (data
->wd_Flags
& MUIWF_BUBBLEMODE
)
1219 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_LATER
;
1223 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_FIRST
;
1230 typedef BOOL (*UNDERCHECK_FUNC
)(Object
*obj
);
1232 static BOOL
ShortHelpUnderPointerCheck(Object
*obj
)
1234 return muiAreaData(obj
)->mad_ShortHelp
? TRUE
: FALSE
;
1237 static Object
*ObjectUnderPointer(struct MUI_WindowData
*data
, Object
*obj
,
1238 LONG x
, LONG y
, UNDERCHECK_FUNC func
)
1242 struct MinList
*ChildList
= NULL
;
1244 if (!(muiAreaData(obj
)->mad_Flags
& MADF_CANDRAW
))
1247 if (!(x
>= _left(obj
) && x
<= _right(obj
)
1248 && y
>= _top(obj
) && y
<= _bottom(obj
)))
1253 if ((get(obj
, MUIA_Group_ChildList
, &(ChildList
))) && (ChildList
!= NULL
))
1255 cstate
= (Object
*)ChildList
->mlh_Head
;
1256 while ((child
= NextObject(&cstate
)))
1260 if ((x
>= _left(child
) && x
<= _right(child
)
1262 y
>= _top(child
) && y
<= _bottom(child
))
1264 (ret
= ObjectUnderPointer(data
, child
, x
, y
, func
)))
1271 if (!(*func
)(obj
)) return NULL
;
1276 static BOOL
ContextMenuUnderPointer(struct MUI_WindowData
*data
, Object
*obj
, LONG x
, LONG y
)
1280 struct MinList
*ChildList
= NULL
;
1282 if (!(x
>= _left(obj
) && x
<= _right(obj
)
1283 && y
>= _top(obj
) && y
<= _bottom(obj
)))
1288 if ((get(obj
, MUIA_Group_ChildList
, &(ChildList
))) && (ChildList
!= NULL
))
1291 cstate
= (Object
*)ChildList
->mlh_Head
;
1292 while ((child
= NextObject(&cstate
)))
1294 if ((x
>= _left(child
) && x
<= _right(child
)
1296 y
>= _top(child
) && y
<= _bottom(child
))
1298 (ContextMenuUnderPointer(data
,child
,x
,y
)))
1303 if (!(muiAreaData(obj
)->mad_Flags
& MADF_CANDRAW
))
1305 if (!(muiAreaData(obj
)->mad_ContextMenu
))
1313 static void ActivateObject (struct MUI_WindowData
*data
)
1315 //bug("Window::ActivateObject (dummy) %08lx\n", data->wd_ActiveObject);
1316 // if (FindObjNode(&data->wd_CycleChain, data->wd_ActiveObject))
1317 // DoMethod(data->wd_ActiveObject, MUIM_GoActive);
1319 // data->wd_ActiveObject = NULL;
1321 //activate better string gadgets.Fix from Georg S On ML List
1322 if (FindObjNode(&data
->wd_CycleChain
, data
->wd_ActiveObject
))
1324 if (!(data
->wd_Flags
& MUIWF_OBJECTGOACTIVESENT
))
1326 data
->wd_Flags
|= MUIWF_OBJECTGOACTIVESENT
;
1327 DoMethod(data
->wd_ActiveObject
, MUIM_GoActive
);
1331 data
->wd_ActiveObject
= NULL
;
1336 static void HandleInputEvent(Object
*win
, struct MUI_WindowData
*data
,
1337 struct IntuiMessage
*event
);
1339 /* handle intuimessage while an object is being dragged
1340 * (reply imsg before returning)
1342 void HandleDragging (Object
*oWin
, struct MUI_WindowData
*data
,
1343 struct IntuiMessage
*imsg
)
1345 struct Window
*iWin
;
1346 int finish_drag
= 0;
1348 iWin
= imsg
->IDCMPWindow
;
1350 if (imsg
->Class
== IDCMP_MOUSEMOVE
)
1352 struct Layer
*layer
;
1353 layer
= WhichLayer(&iWin
->WScreen
->LayerInfo
, iWin
->LeftEdge
+ imsg
->MouseX
, iWin
->TopEdge
+ imsg
->MouseY
);
1355 if (data
->wd_DropObject
)
1358 WORD mousex
= imsg
->MouseX
+ iWin
->LeftEdge
- data
->wd_DropWindow
->LeftEdge
;
1359 WORD mousey
= imsg
->MouseY
+ iWin
->TopEdge
- data
->wd_DropWindow
->TopEdge
;
1361 wnd
= _window(data
->wd_DropObject
);
1364 mousex
< _left(data
->wd_DropObject
)
1365 || mousex
> _right(data
->wd_DropObject
)
1366 || mousey
< _top(data
->wd_DropObject
)
1367 || mousey
> _bottom(data
->wd_DropObject
)
1368 || layer
!= wnd
->WLayer
1371 /* We have left the object */
1372 UndrawDragNDrop(data
->wd_dnd
);
1373 DoMethod(data
->wd_DropObject
, MUIM_DragFinish
,(IPTR
)data
->wd_DragObject
);
1374 data
->wd_DropObject
= NULL
;
1376 } /* if (data->wd_DropObject) */
1378 if (!data
->wd_DropObject
)
1380 Object
*dest_wnd
= NULL
;
1382 /* Find out if app has an openend window at this position */
1387 struct MinList
*ChildList
= 0;
1389 get(_app(oWin
), MUIA_Application_WindowList
, &(ChildList
));
1390 cstate
= (Object
*)ChildList
->mlh_Head
;
1391 while ((child
= NextObject(&cstate
)))
1393 struct Window
*wnd
= NULL
;
1394 get(child
, MUIA_Window_Window
,&wnd
);
1397 if (wnd
->WLayer
== layer
)
1399 data
->wd_DropWindow
= wnd
;
1408 Object
*root
= NULL
;
1409 get(dest_wnd
, MUIA_Window_RootObject
, &root
);
1416 data
->wd_DropObject
= (Object
*) DoMethod
1418 root
, MUIM_DragQueryExtended
,
1419 (IPTR
) data
->wd_DragObject
,
1420 imsg
->MouseX
+ iWin
->LeftEdge
- data
->wd_DropWindow
->LeftEdge
,
1421 imsg
->MouseY
+ iWin
->TopEdge
- data
->wd_DropWindow
->TopEdge
1426 UndrawDragNDrop(data
->wd_dnd
);
1427 DoMethod(data
->wd_DropObject
, MUIM_DragBegin
,(IPTR
)data
->wd_DragObject
);
1430 } /* if (dest_wnd) */
1431 } /* if (!data->wd_DropObject) */
1433 if (data
->wd_DropObject
)
1441 data
->wd_DropObject
, MUIM_DragReport
,
1442 (IPTR
) data
->wd_DragObject
,
1443 imsg
->MouseX
+ iWin
->LeftEdge
- data
->wd_DropWindow
->LeftEdge
,
1444 imsg
->MouseY
+ iWin
->TopEdge
- data
->wd_DropWindow
->TopEdge
,update
1448 case MUIV_DragReport_Abort
:
1449 UndrawDragNDrop(data
->wd_dnd
);
1450 DoMethod(data
->wd_DropObject
, MUIM_DragFinish
,(IPTR
)data
->wd_DragObject
);
1451 data
->wd_DropObject
= NULL
;
1455 case MUIV_DragReport_Continue
: break;
1456 case MUIV_DragReport_Lock
: break; /* NYI */
1457 case MUIV_DragReport_Refresh
:
1458 UndrawDragNDrop(data
->wd_dnd
);
1463 } /* if (data->wd_DropObject) */
1464 DrawDragNDrop(data
->wd_dnd
, imsg
->MouseX
+ iWin
->LeftEdge
, imsg
->MouseY
+ iWin
->TopEdge
);
1465 } /* if (imsg->Class == IDCMP_MOUSEMOVE) */
1467 if (imsg
->Class
== IDCMP_MOUSEBUTTONS
)
1469 if ((imsg
->Code
== MENUDOWN
) || (imsg
->Code
== SELECTUP
))
1471 if (imsg
->Code
== SELECTUP
&& data
->wd_DropObject
)
1473 UndrawDragNDrop(data
->wd_dnd
);
1474 DoMethod(data
->wd_DropObject
, MUIM_DragFinish
, (IPTR
)data
->wd_DragObject
);
1477 data
->wd_DropObject
, MUIM_DragDrop
, (IPTR
)data
->wd_DragObject
,
1478 imsg
->MouseX
+ iWin
->LeftEdge
- data
->wd_DropWindow
->LeftEdge
,
1479 imsg
->MouseY
+ iWin
->TopEdge
- data
->wd_DropWindow
->TopEdge
1481 data
->wd_DropObject
= NULL
;
1483 else if (imsg
->Code
== SELECTUP
)
1485 DoMethod(data
->wd_DragObject
, MUIM_UnknownDropDestination
, imsg
);
1491 if (imsg
->Class
== IDCMP_CLOSEWINDOW
)
1496 UndrawDragNDrop(data
->wd_dnd
);
1497 if (data
->wd_DropObject
)
1499 DoMethod(data
->wd_DropObject
, MUIM_DragFinish
, (IPTR
)data
->wd_DragObject
);
1500 data
->wd_DropObject
= NULL
;
1502 DeleteDragNDrop(data
->wd_dnd
);
1503 DoMethod(data
->wd_DragObject
, MUIM_DeleteDragImage
, (IPTR
)data
->wd_DragImage
);
1504 muiAreaData(data
->wd_DragObject
)->mad_Flags
&= ~MADF_DRAGGING
;
1505 data
->wd_DragImage
= NULL
;
1506 data
->wd_DragObject
= NULL
;
1507 data
->wd_DropWindow
= NULL
;
1508 data
->wd_dnd
= NULL
;
1509 /* stop listening to IDCMP_MOUSEMOVE */
1510 ChangeEvents(data
, GetDefaultEvents());
1512 ReplyMsg((struct Message
*)imsg
);
1515 /* Reply to imsg if handled */
1516 BOOL
HandleWindowEvent (Object
*oWin
, struct MUI_WindowData
*data
,
1517 struct IntuiMessage
*imsg
)
1519 struct Window
*iWin
;
1520 BOOL is_handled
= TRUE
;
1521 BOOL replied
= FALSE
;
1523 iWin
= imsg
->IDCMPWindow
;
1524 switch (imsg
->Class
)
1526 case IDCMP_ACTIVEWINDOW
:
1527 data
->wd_Flags
|= MUIWF_ACTIVE
;
1528 if (data
->wd_OldActive
)
1529 set(oWin
, MUIA_Window_ActiveObject
, data
->wd_OldActive
);
1530 set(oWin
, MUIA_Window_Activate
, TRUE
);
1531 is_handled
= FALSE
; /* forwardable to area event handlers */
1534 case IDCMP_INACTIVEWINDOW
:
1535 KillHelpBubble(data
, oWin
, TRUE
);
1536 if (data
->wd_ActiveObject
)
1538 data
->wd_OldActive
= data
->wd_ActiveObject
;
1539 set(oWin
, MUIA_Window_ActiveObject
, MUIV_Window_ActiveObject_None
);
1541 data
->wd_Flags
&= ~MUIWF_ACTIVE
;
1542 set(oWin
, MUIA_Window_Activate
, FALSE
);
1543 is_handled
= FALSE
; /* forwardable to area event handlers */
1547 ReplyMsg((struct Message
*)imsg
);
1551 int hborders
= iWin
->BorderLeft
+ iWin
->BorderRight
;
1552 int vborders
= iWin
->BorderTop
+ iWin
->BorderBottom
;
1554 /* set window limits according to window contents */
1558 data
->wd_MinMax
.MinWidth
+ hborders
,
1559 data
->wd_MinMax
.MinHeight
+ vborders
,
1560 data
->wd_MinMax
.MaxWidth
+ hborders
,
1561 data
->wd_MinMax
.MaxHeight
+ vborders
1565 if ((iWin
->GZZWidth
!= data
->wd_Width
) || (iWin
->GZZHeight
!= data
->wd_Height
))
1567 data
->wd_Width
= iWin
->GZZWidth
;
1568 data
->wd_Height
= iWin
->GZZHeight
;
1569 DoHideMethod(data
->wd_RootObject
);
1571 if (1) // why only simple refresh? was: if (data->wd_RenderInfo.mri_Window->Flags & WFLG_SIMPLE_REFRESH)
1573 data
->wd_Flags
|= MUIWF_RESIZING
;
1577 _width(data
->wd_RootObject
) = data
->wd_Width
;
1578 _height(data
->wd_RootObject
) = data
->wd_Height
;
1579 DoMethod(data
->wd_RootObject
, MUIM_Layout
);
1580 DoShowMethod(data
->wd_RootObject
);
1582 LONG left
,top
,width
,height
;
1584 left
= data
->wd_RenderInfo
.mri_Window
->BorderLeft
;
1585 top
= data
->wd_RenderInfo
.mri_Window
->BorderTop
,
1586 width
= data
->wd_RenderInfo
.mri_Window
->Width
1587 - data
->wd_RenderInfo
.mri_Window
->BorderRight
- left
;
1588 height
= data
->wd_RenderInfo
.mri_Window
->Height
1589 - data
->wd_RenderInfo
.mri_Window
->BorderBottom
- top
;
1591 // D(bug("%d:zune_imspec_draw(%p) l=%d t=%d w=%d h=%d xo=%d yo=%d\n",
1592 // __LINE__, data->wd_Background, left, top, width,
1593 // height, left, top));
1594 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
1595 left
, top
, width
, height
, left
, top
, 0);
1597 if (muiGlobalInfo(oWin
)->mgi_Prefs
->window_redraw
== WINDOW_REDRAW_WITHOUT_CLEAR
)
1598 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWOBJECT
);
1600 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWALL
);
1601 // but should only draw focus without using MUIM_GoActive !
1602 ActivateObject(data
);
1607 case IDCMP_REFRESHWINDOW
:
1608 ReplyMsg((struct Message
*)imsg
);
1610 if (data
->wd_Flags
& MUIWF_RESIZING
)
1612 //LONG left,top,right,bottom;
1613 if (MUI_BeginRefresh(&data
->wd_RenderInfo
, 0))
1615 MUI_EndRefresh(&data
->wd_RenderInfo
, 0);
1617 RefreshWindowFrame(data
->wd_RenderInfo
.mri_Window
);
1619 data
->wd_Flags
&= ~MUIWF_RESIZING
;
1620 _width(data
->wd_RootObject
) = data
->wd_Width
;
1621 _height(data
->wd_RootObject
) = data
->wd_Height
;
1622 DoMethod(data
->wd_RootObject
, MUIM_Layout
);
1623 DoShowMethod(data
->wd_RootObject
);
1625 if (muiGlobalInfo(oWin
)->mgi_Prefs
->window_redraw
== WINDOW_REDRAW_WITH_CLEAR
)
1627 LONG left
,top
,width
,height
;
1629 left
= data
->wd_RenderInfo
.mri_Window
->BorderLeft
;
1630 top
= data
->wd_RenderInfo
.mri_Window
->BorderTop
;
1631 width
= data
->wd_RenderInfo
.mri_Window
->Width
- data
->wd_RenderInfo
.mri_Window
->BorderRight
- left
;
1632 height
= data
->wd_RenderInfo
.mri_Window
->Height
- data
->wd_RenderInfo
.mri_Window
->BorderBottom
- top
;
1634 if(data
->wd_Flags
& MUIWF_ERASEAREA
)
1636 // D(bug("%d:zune_imspec_draw(%p) l=%d t=%d w=%d h=%d xo=%d yo=%d\n",
1637 // __LINE__, data->wd_Background, left, top, width,
1638 // height, left, top));
1639 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
1640 left
, top
, width
, height
, left
, top
, 0);
1642 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWALL
);
1645 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWOBJECT
);
1646 // but should only draw focus without using MUIM_GoActive !
1647 ActivateObject(data
);
1651 if (MUI_BeginRefresh(&data
->wd_RenderInfo
, 0))
1653 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWALL
);
1654 // but should only draw focus without using MUIM_GoActive !
1655 ActivateObject(data
);
1656 MUI_EndRefresh(&data
->wd_RenderInfo
, 0);
1661 case IDCMP_CLOSEWINDOW
:
1662 ReplyMsg((struct Message
*)imsg
);
1664 set(oWin
, MUIA_Window_CloseRequest
, TRUE
);
1667 case IDCMP_MENUPICK
:
1668 ReplyMsg((struct Message
*)imsg
);
1673 if (MENUNUM(imsg
->Code
) != NOMENU
&& ITEMNUM(imsg
->Code
) != NOITEM
)
1675 struct MenuItem
*item
= ItemAddress(data
->wd_Menu
,imsg
->Code
);
1678 Object
*item_obj
= (Object
*)GTMENUITEM_USERDATA(item
);
1684 if (item
->Flags
& CHECKIT
)
1685 set(item_obj
, MUIA_Menuitem_Checked
, !!(item
->Flags
& CHECKED
));
1687 set(item_obj
, MUIA_Menuitem_Trigger
, (IPTR
)item
);
1689 get(oWin
, MUIA_ApplicationObject
, &app
);
1690 get(item_obj
, MUIA_UserData
, &udata
);
1692 set(app
, MUIA_Application_MenuAction
, udata
);
1693 set(oWin
, MUIA_Window_MenuAction
, udata
);
1694 DoMethod(app
, MUIM_Application_ReturnID
, udata
);
1701 case IDCMP_IDCMPUPDATE
:
1702 is_handled
= FALSE
; /* forwardable to area event handlers */
1703 if (data
->wd_VertProp
|| data
->wd_HorizProp
)
1705 struct TagItem
*tag
;
1706 tag
= FindTagItem(GA_ID
,(struct TagItem
*)imsg
->IAddress
);
1709 /* If there's a propclass object connected to the prop
1710 gadget, the prop gadget's userdata will point to
1711 that propclass object. See classes/prop.c */
1713 if (data
->wd_VertProp
)
1715 if (tag
->ti_Data
== GADGETID(data
->wd_VertProp
))
1718 if (tag
->ti_Data
== GADGETID(data
->wd_UpButton
))
1720 Object
*prop
= (Object
*)((struct Gadget
*)data
->wd_VertProp
)->UserData
;
1722 if (prop
) DoMethod(prop
, MUIM_Prop_Decrease
, 1);
1725 if (tag
->ti_Data
== GADGETID(data
->wd_DownButton
))
1727 Object
*prop
= (Object
*)((struct Gadget
*)data
->wd_VertProp
)->UserData
;
1729 if (prop
) DoMethod(prop
, MUIM_Prop_Increase
, 1);
1734 if (data
->wd_HorizProp
)
1736 if (tag
->ti_Data
== GADGETID(data
->wd_HorizProp
))
1739 if (tag
->ti_Data
== GADGETID(data
->wd_LeftButton
))
1741 Object
*prop
= (Object
*)((struct Gadget
*)data
->wd_HorizProp
)->UserData
;
1743 if (prop
) DoMethod(prop
, MUIM_Prop_Decrease
, 1);
1746 if (tag
->ti_Data
== GADGETID(data
->wd_RightButton
))
1748 Object
*prop
= (Object
*)((struct Gadget
*)data
->wd_HorizProp
)->UserData
;
1750 if (prop
) DoMethod(prop
, MUIM_Prop_Increase
, 1);
1758 case IDCMP_INTUITICKS
:
1759 if (data
->wd_HelpTicker
)
1761 data
->wd_HelpTicker
--;
1763 if (data
->wd_HelpTicker
== 0)
1765 Object
*underobj
= ObjectUnderPointer(data
, data
->wd_RootObject
, imsg
->MouseX
, imsg
->MouseY
,
1766 ShortHelpUnderPointerCheck
);
1768 if (underobj
!= data
->wd_HelpObject
)
1770 if (data
->wd_HelpObject
)
1772 DoMethod(data
->wd_HelpObject
, MUIM_DeleteBubble
, (IPTR
)data
->wd_HelpBubble
);
1774 data
->wd_HelpObject
= NULL
;
1775 data
->wd_HelpBubble
= NULL
;
1780 data
->wd_HelpBubble
= (APTR
)DoMethod(underobj
, MUIM_CreateBubble
,
1781 imsg
->MouseX
, imsg
->MouseY
,
1783 if (data
->wd_HelpBubble
)
1785 data
->wd_HelpObject
= underobj
;
1786 data
->wd_Flags
|= MUIWF_BUBBLEMODE
;
1791 if (data
->wd_Flags
& MUIWF_BUBBLEMODE
)
1793 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_LATER
;
1797 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_FIRST
;
1800 } /* if (data->wd_HelpTicker == 0) */
1802 } /* if (data->wd_HelpTicker) */
1804 is_handled
= FALSE
; /* forwardable to area event handlers */
1807 case IDCMP_MOUSEBUTTONS
:
1808 DoMethod(oWin
,MUIM_Window_Snapshot
,0);
1809 KillHelpBubble(data
, oWin
, TRUE
);
1814 case IDCMP_MOUSEMOVE
:
1815 KillHelpBubble(data
, oWin
, FALSE
);
1822 } /* switch (imsg->Class) */
1824 if (is_handled
&& !replied
)
1825 ReplyMsg((struct Message
*)imsg
);
1830 static ULONG
InvokeEventHandler (struct MUI_EventHandlerNode
*ehn
,
1831 struct IntuiMessage
*event
, ULONG muikey
)
1835 if (!(_flags(ehn
->ehn_Object
) & MADF_CANDRAW
)) return 0;
1836 if (!(_flags(ehn
->ehn_Object
) & MADF_SHOWME
)) return 0;
1841 && event
->Class
== IDCMP_MOUSEBUTTONS
1842 && event
->Code
== SELECTDOWN
1843 && (_flags(ehn
->ehn_Object
) & MADF_INVIRTUALGROUP
)
1847 Here we filter out SELECTDOWN messages if objects is in a virtual
1848 group but the click went out of the virtual group
1850 Object
*obj
= ehn
->ehn_Object
;
1851 Object
*parent
= obj
;
1852 Object
*wnd
= _win(obj
);
1854 while (get(parent
,MUIA_Parent
,&parent
))
1857 if (wnd
== parent
) break;
1858 if (_flags(parent
) & MADF_ISVIRTUALGROUP
)
1862 event
->MouseX
< _mleft(parent
)
1863 || event
->MouseX
> _mright(parent
)
1864 || event
->MouseY
< _mtop(parent
)
1865 || event
->MouseY
> _mbottom(parent
)
1875 if (ehn
->ehn_Flags
& MUI_EHF_HANDLEINPUT
)
1877 DoMethod(ehn
->ehn_Object
, MUIM_HandleInput
, (IPTR
)event
, muikey
);
1885 ehn
->ehn_Class
, ehn
->ehn_Object
, MUIM_HandleEvent
,
1889 res
= DoMethod(ehn
->ehn_Object
, MUIM_HandleEvent
, (IPTR
)event
, muikey
);
1894 static void HandleRawkey(Object
*win
, struct MUI_WindowData
*data
,
1895 struct IntuiMessage
*event
)
1898 struct MUI_EventHandlerNode
*ehn
;
1899 struct IntuiMessage imsg_copy
;
1900 struct InputEvent ie
= {0};
1902 LONG muikey
= MUIKEY_NONE
;
1903 Object
*active_object
= NULL
;
1908 KillHelpBubble(data
, win
, BUBBLEHELP_TICKER_FIRST
);
1910 ie
.ie_NextEvent
= NULL
;
1911 ie
.ie_Class
= IECLASS_RAWKEY
;
1913 ie
.ie_Code
= event
->Code
;
1914 ie
.ie_Qualifier
= event
->Qualifier
;
1915 ie
.ie_EventAddress
= (APTR
)*(IPTR
*)event
->IAddress
;
1917 ie
.ie_TimeStamp
.Seconds
= event
->Seconds
;
1918 ie
.ie_TimeStamp
.Microseconds
= event
->Micros
;
1920 ie
.ie_TimeStamp
.tv_secs
= event
->Seconds
;
1921 ie
.ie_TimeStamp
.tv_micro
= event
->Micros
;
1924 set(win
, MUIA_Window_InputEvent
, (IPTR
)&ie
);
1926 /* get the vanilla key for control char */
1929 /* Remove the up prefix as convert key does not convert a upkey event */
1930 msg_code
= event
->Code
;
1931 event
->Code
&= ~IECODE_UP_PREFIX
;
1932 key
= ConvertKey(event
);
1933 event
->Code
= msg_code
;
1937 deadkey
= *(ULONG
*)event
->IAddress
;
1938 imsg_copy
.IAddress
= &deadkey
;
1939 ReplyMsg((struct Message
*)event
);
1942 //bug("rawkey: code=%lx, qual=%lx\n", event->Code, event->Qualifier);
1944 /* check if imsg translate to predefined keystroke */
1946 struct InputEvent ievent
;
1947 BOOL matched
= FALSE
;
1949 ievent
.ie_NextEvent
= NULL
;
1950 ievent
.ie_Class
= IECLASS_RAWKEY
;
1951 ievent
.ie_SubClass
= 0;
1952 ievent
.ie_Code
= event
->Code
;
1953 ievent
.ie_Qualifier
= event
->Qualifier
;
1954 /* ie_EventAddress is not used by MatchIX. If needed, it should be
1955 * ensured that it is still a valid adress because of the shallow
1956 * IntuiMessage copy currently done in _zune_window_message before
1957 * message is replied.
1959 ievent
.ie_EventAddress
= NULL
;
1960 //ievent.ie_EventAddress = (APTR *) *((ULONG *)(event->IAddress));
1962 for (muikey
= MUIKEY_COUNT
- 1; muikey
>= MUIKEY_PRESS
; muikey
--)
1964 if (muiGlobalInfo(win
)->mgi_Prefs
->muikeys
[muikey
].ix_well
!= 0
1965 && MatchIX(&ievent
, &muiGlobalInfo(win
)->mgi_Prefs
->muikeys
[muikey
].ix
))
1974 if (muikey
== MUIKEY_PRESS
&& (event
->Code
& IECODE_UP_PREFIX
))
1975 muikey
= MUIKEY_RELEASE
;
1979 muikey
= MUIKEY_NONE
;
1981 } /* check if imsg translate to predefined keystroke */
1983 if ((muikey
!= MUIKEY_NONE
)
1984 && !(data
->wd_DisabledKeys
& (1<<muikey
)))
1986 D(bug("HandleRawkey: try MUIKEY %ld on window %0x08lx\n", muikey
, win
));
1989 case MUIKEY_PRESS
: break;
1990 case MUIKEY_TOGGLE
: break;
1991 case MUIKEY_UP
: break;
1992 case MUIKEY_DOWN
: break;
1993 case MUIKEY_PAGEUP
: break;
1994 case MUIKEY_PAGEDOWN
: break;
1995 case MUIKEY_TOP
: break;
1996 case MUIKEY_BOTTOM
: break;
1997 case MUIKEY_LEFT
: break;
1998 case MUIKEY_RIGHT
: break;
1999 case MUIKEY_WORDLEFT
: break;
2000 case MUIKEY_WORDRIGHT
: break;
2001 case MUIKEY_LINESTART
: break;
2002 case MUIKEY_LINEEND
: break;
2003 case MUIKEY_GADGET_NEXT
:
2004 set(win
, MUIA_Window_ActiveObject
, MUIV_Window_ActiveObject_Next
);
2006 case MUIKEY_GADGET_PREV
:
2007 set(win
, MUIA_Window_ActiveObject
, MUIV_Window_ActiveObject_Prev
);
2009 case MUIKEY_GADGET_OFF
:
2010 set(win
, MUIA_Window_ActiveObject
, MUIV_Window_ActiveObject_None
);
2012 case MUIKEY_WINDOW_CLOSE
:
2013 set(win
, MUIA_Window_CloseRequest
, TRUE
);
2015 case MUIKEY_WINDOW_NEXT
: break;
2016 case MUIKEY_WINDOW_PREV
: break;
2017 case MUIKEY_HELP
: break;
2018 case MUIKEY_POPUP
: break;
2023 active_object
= NULL
;
2024 if ((data
->wd_ActiveObject
!= NULL
)
2025 && (DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
2026 (IPTR
)data
->wd_ActiveObject
) != (IPTR
)NULL
))
2028 active_object
= data
->wd_ActiveObject
;
2029 get(active_object
, MUIA_Disabled
, &disabled
);
2032 data
->wd_ActiveObject
= NULL
;
2034 /* try ActiveObject */
2035 if ((active_object
!= NULL
) && !disabled
)
2039 ** Which method should be used for muikeys? MUIM_HandleInput or
2040 ** MUIM_HandleEvent. Also note that there is a flag MUI_EHF_ALWAYSKEYS
2041 ** which probably means that all keys events are requested??
2042 ** For now MUIM_HandleEvent is used as this is currently implemented
2043 ** in Area class ;) although I guess it should be MUIM_HandleInput as this
2047 if (muikey
!= MUIKEY_NONE
)
2049 res
= DoMethod(active_object
, MUIM_HandleEvent
, (IPTR
)event
, muikey
);
2050 if (res
& MUI_EventHandlerRC_Eat
) return;
2053 D(bug("HandleRawkey: try active object (%08lx) handlers\n", active_object
));
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
== active_object
)
2060 && ((ehn
->ehn_Events
& IDCMP_RAWKEY
)
2061 || (ehn
->ehn_Flags
& MUI_EHF_ALWAYSKEYS
)))
2063 D(bug("HandleRawkey: (active) invoking on %p (ehn=%p) event=%p muikey=%p\n",
2064 ehn
->ehn_Object
, ehn
, event
, muikey
));
2065 res
= InvokeEventHandler(ehn
, event
, muikey
);
2066 D(bug("HandleRawkey: (active) got res=%d\n", res
));
2067 if (res
& MUI_EventHandlerRC_Eat
)
2070 /* Leave the loop if a different object has been activated */
2071 if (active_object
!= data
->wd_ActiveObject
)
2074 } /* for (mn = data->wd_EHList.mlh_Head; mn->mln_Succ; mn = mn->mln_Succ) */
2076 // event not eaten by active object, try its parents
2077 // this is to implement popup key in Popstring
2078 if (active_object
== data
->wd_ActiveObject
)
2080 Object
*current_obj
= active_object
;
2082 D(bug("HandleRawkey: try active object parents handlers\n"));
2083 while (current_obj
!= NULL
)
2085 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2087 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2089 if ((ehn
->ehn_Object
== current_obj
)
2090 && ((ehn
->ehn_Events
& IDCMP_RAWKEY
)
2091 || (ehn
->ehn_Flags
& MUI_EHF_ALWAYSKEYS
)))
2093 //D(bug("HandleRawkey: (active parents) invoking on %p (ehn=%p) "
2094 //"event=%p muikey=%p\n",
2095 //ehn->ehn_Object, ehn, event, muikey));
2096 res
= InvokeEventHandler(ehn
, event
, muikey
);
2097 //D(bug("HandleRawkey: (active parents) got res=%d\n", res));
2098 if (res
& MUI_EventHandlerRC_Eat
)
2101 /* Leave the loop if a different object has been activated */
2102 if (active_object
!= data
->wd_ActiveObject
)
2106 current_obj
= (Object
*)XGET(current_obj
, MUIA_Parent
);
2107 } // while (current_obj != NULL)
2109 } /* if (active_object && !disabled) */
2111 D(bug("HandleRawkey: try default object handlers\n"));
2113 /* try DefaultObject */
2114 if (data
->wd_DefaultObject
!= NULL
)
2115 get(data
->wd_DefaultObject
, MUIA_Disabled
, &disabled
);
2117 if ((data
->wd_DefaultObject
!= NULL
) && !disabled
2118 && (active_object
!= data
->wd_DefaultObject
))
2120 /* No, we only should do this if the object actually has requested this via RequestIDCMP()! */
2121 // if (muikey != MUIKEY_NONE && (_flags(data->wd_DefaultObject) & MADF_CANDRAW))
2123 // DoMethod(data->wd_DefaultObject, MUIM_HandleInput, event, muikey);
2127 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2129 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2131 if ((ehn
->ehn_Object
== data
->wd_DefaultObject
)
2132 && ((ehn
->ehn_Events
& IDCMP_RAWKEY
)
2133 || (ehn
->ehn_Flags
& MUI_EHF_ALWAYSKEYS
)))
2135 //D(bug("HandleRawkey: (default) invoking on %p (ehn=%p) event=%p muikey=%p\n",
2136 //ehn->ehn_Object, ehn, event, muikey));
2137 res
= InvokeEventHandler(ehn
, event
, muikey
);
2138 //D(bug("HandleRawkey: (default) got res=%d\n", res));
2139 if (res
& MUI_EventHandlerRC_Eat
)
2144 } /* if ... default object */
2146 D(bug("HandleRawkey: try other handlers\n"));
2148 // try other handlers
2149 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2151 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2153 // skip Active and Default object as they have already been
2155 if (ehn
->ehn_Object
== data
->wd_ActiveObject
|| ehn
->ehn_Object
== data
->wd_DefaultObject
)
2158 if (ehn
->ehn_Events
& IDCMP_RAWKEY
)
2160 //D(bug("HandleRawkey: (others) invoking on %p (ehn=%p) event=%p muikey=%p\n",
2161 //ehn->ehn_Object, ehn, event, muikey));
2162 res
= InvokeEventHandler(ehn
, event
, MUIKEY_NONE
);
2163 //D(bug("HandleRawkey: (others) got res=%d\n", res));
2164 if (res
& MUI_EventHandlerRC_Eat
)
2167 } /* for (mn = data->wd_EHList.mlh_Head; mn->mln_Succ; mn = mn->mln_Succ) */
2169 D(bug("HandleRawkey: try control chars handlers\n"));
2171 /* try Control Chars */
2172 //bug("ctrlchar, key='%c' code=0x%08lx\n", key, event->Code);
2175 for (mn
= data
->wd_CCList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2177 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2179 if (ehn
->ehn_Events
== key
)
2182 LONG muikey2
= ehn
->ehn_Flags
;
2184 get(ehn
->ehn_Object
, MUIA_Disabled
, &disabled
);
2188 //bug("control char\n");
2189 if (event
->Code
& IECODE_UP_PREFIX
)
2191 /* simulate a release */
2192 if (muikey2
== MUIKEY_PRESS
)
2193 muikey2
= MUIKEY_RELEASE
;
2198 if ((muikey2
!= MUIKEY_NONE
)
2199 && (_flags(ehn
->ehn_Object
) & MADF_CANDRAW
)
2200 && (_flags(ehn
->ehn_Object
) & MADF_SHOWME
))
2204 ehn
->ehn_Class
, ehn
->ehn_Object
, MUIM_HandleEvent
,
2207 if (res
& MUI_EventHandlerRC_Eat
)
2212 } /* try control chars */
2215 /* forward non-keystroke events to event handlers */
2216 static void HandleInputEvent(Object
*win
, struct MUI_WindowData
*data
,
2217 struct IntuiMessage
*event
)
2220 struct MUI_EventHandlerNode
*ehn
;
2221 struct IntuiMessage imsg_copy
;
2223 ULONG mask
= event
->Class
;
2225 if (mask
!= IDCMP_IDCMPUPDATE
)
2228 imsg_copy
.IAddress
= NULL
; /* be sure to trap access to that */
2229 ReplyMsg((struct Message
*)event
);
2233 if (mask
== IDCMP_MOUSEMOVE
)
2235 struct Window
*iWin
;
2236 iWin
= event
->IDCMPWindow
;
2238 if (ContextMenuUnderPointer (data
, data
->wd_RootObject
,
2239 event
->MouseX
, event
->MouseY
))
2241 iWin
->Flags
|= WFLG_RMBTRAP
;
2243 else if (!data
->wd_NoMenus
)
2245 iWin
->Flags
&= ~WFLG_RMBTRAP
;
2249 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2251 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2253 if (ehn
->ehn_Events
& mask
)
2257 get(ehn
->ehn_Object
, MUIA_Disabled
, &disabled
);
2261 res
= InvokeEventHandler(ehn
, event
, MUIKEY_NONE
);
2262 if (res
& MUI_EventHandlerRC_Eat
)
2268 if (mask
== IDCMP_IDCMPUPDATE
)
2269 ReplyMsg((struct Message
*)event
);
2273 /* process window message, this does a ReplyMsg() to the message */
2274 /* Called from application.c */
2275 void _zune_window_message(struct IntuiMessage
*imsg
)
2277 struct Window
*iWin
;
2279 struct MUI_WindowData
*data
;
2282 iWin
= imsg
->IDCMPWindow
;
2283 oWin
= (Object
*)iWin
->UserData
;
2284 data
= muiWindowData(oWin
);
2286 if (data
->wd_DragObject
)
2288 HandleDragging(oWin
, data
, imsg
);
2292 handled
= HandleWindowEvent(oWin
, data
, imsg
);
2295 if (IDCMP_RAWKEY
== imsg
->Class
)
2296 HandleRawkey(oWin
, data
, imsg
);
2297 else if (IDCMP_GADGETUP
== imsg
->Class
)
2300 if (ETI_MUI
== ((struct Gadget
*) imsg
->IAddress
)->GadgetID
)
2302 DoMethod(_app(oWin
), MUIM_Application_OpenConfigWindow
);
2305 if (ETI_Iconify
== ((struct Gadget
*)imsg
->IAddress
)->GadgetID
)
2307 set(_app(oWin
), MUIA_Application_Iconified
, TRUE
);
2312 HandleInputEvent(oWin
, data
, imsg
);
2317 /******************************************************************************/
2318 /******************************************************************************/
2320 /* code for setting MUIA_Window_RootObject */
2321 static void ChangeRootObject (struct MUI_WindowData
*data
, Object
*obj
,
2326 ASSERT_VALID_PTR(data
);
2327 ASSERT_VALID_PTR(obj
);
2329 oldRoot
= data
->wd_RootObject
;
2330 if (!(data
->wd_Flags
& MUIWF_OPENED
))
2334 if (data
->wd_ActiveObject
== oldRoot
)
2335 set(obj
, MUIA_Window_ActiveObject
, MUIV_Window_ActiveObject_None
);
2336 DoMethod(oldRoot
, MUIM_DisconnectParent
);
2339 data
->wd_RootObject
= newRoot
;
2342 /* if window is in App tree, inform child */
2343 if (muiNotifyData(obj
)->mnd_GlobalInfo
)
2344 DoMethod(newRoot
, MUIM_ConnectParent
, (IPTR
)obj
);
2349 // find the ObjNode containing a pointer to the given object
2350 // currently only used for cycle chain objects
2351 static struct ObjNode
*FindObjNode(struct MinList
*list
, Object
*obj
)
2353 struct ObjNode
*node
;
2355 ASSERT_VALID_PTR(list
);
2360 ASSERT_VALID_PTR(obj
);
2362 for (node
= (struct ObjNode
*)list
->mlh_Head
;
2363 node
->node
.mln_Succ
;
2364 node
= (struct ObjNode
*)node
->node
.mln_Succ
)
2366 if (node
->obj
== obj
)
2374 static Object
*GetFirstActiveObject (struct MUI_WindowData
*data
)
2376 ASSERT_VALID_PTR(data
);
2378 if (!IsListEmpty((struct List
*)&data
->wd_CycleChain
))
2379 return ((struct ObjNode
*)data
->wd_CycleChain
.mlh_Head
)->obj
;
2384 static Object
*GetLastActiveObject (struct MUI_WindowData
*data
)
2386 ASSERT_VALID_PTR(data
);
2388 if (!IsListEmpty((struct List
*)&data
->wd_CycleChain
))
2389 return ((struct ObjNode
*)data
->wd_CycleChain
.mlh_TailPred
)->obj
;
2394 typedef struct ObjNode
*objnode_iterator_t(struct ObjNode
*curr_node
);
2396 static objnode_iterator_t NextObjNodeIterator
;
2397 static objnode_iterator_t PrevObjNodeIterator
;
2399 static struct ObjNode
*NextObjNodeIterator (struct ObjNode
*curr_node
)
2401 if (curr_node
->node
.mln_Succ
->mln_Succ
)
2402 return (struct ObjNode
*)curr_node
->node
.mln_Succ
;
2407 static struct ObjNode
*PrevObjNodeIterator (struct ObjNode
*curr_node
)
2409 if (curr_node
->node
.mln_Pred
->mln_Pred
)
2410 return (struct ObjNode
*)curr_node
->node
.mln_Pred
;
2415 static Object
*GetPrevNextActiveObject (struct ObjNode
*old_activenode
, objnode_iterator_t node_iterator
)
2417 struct ObjNode
*curr_node
;
2418 struct ObjNode
*node
;
2421 ASSERT_VALID_PTR(old_activenode
);
2423 curr_node
= old_activenode
;
2429 node
= node_iterator(curr_node
);
2434 /* let's see if this obj meets cycle requirements (enabled & visible) */
2437 IPTR is_disabled
= 0;
2439 get(obj
, MUIA_Disabled
, &is_disabled
);
2441 if (!is_disabled
&& (_flags(obj
) & MADF_SHOWME
))
2455 /**************************************************************************
2456 Code for setting MUIA_Window_ActiveObject
2458 - remove focus drawing for current active object
2459 - find (if needed) the new active object
2460 - set data->wd_ActiveObject to the new object
2461 - draw focus around the new active object
2462 **************************************************************************/
2463 static void SetActiveObject (struct MUI_WindowData
*data
, Object
*obj
, IPTR newval
)
2465 struct ObjNode
*old_activenode
= NULL
;
2467 ASSERT_VALID_PTR(data
);
2468 ASSERT_VALID_PTR(obj
);
2470 D(bug("MUIC_Window:SetActiveObject(data, obj, %08lx) Active=%p\n",
2471 newval
, data
->wd_ActiveObject
));
2473 if ((data
->wd_ActiveObject
!= NULL
)
2474 && (DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
2475 (IPTR
)data
->wd_ActiveObject
) != (IPTR
)NULL
))
2477 if ((IPTR
)data
->wd_ActiveObject
!= newval
)
2479 old_activenode
= FindObjNode(&data
->wd_CycleChain
, data
->wd_ActiveObject
);
2480 //if (_flags(data->wd_ActiveObject) & MADF_CANDRAW)
2481 if (data
->wd_Flags
& MUIWF_OBJECTGOACTIVESENT
)
2483 D(bug("Inactivate=%p\n", data
->wd_ActiveObject
));
2484 DoMethod(data
->wd_ActiveObject
, MUIM_GoInactive
);
2489 data
->wd_ActiveObject
= NULL
;
2490 data
->wd_Flags
&= ~MUIWF_OBJECTGOACTIVESENT
;
2494 case MUIV_Window_ActiveObject_None
:
2497 case MUIV_Window_ActiveObject_Next
:
2498 if (old_activenode
!= NULL
)
2499 data
->wd_ActiveObject
= GetPrevNextActiveObject(old_activenode
,
2500 NextObjNodeIterator
);
2501 if (NULL
== data
->wd_ActiveObject
)
2502 data
->wd_ActiveObject
= GetFirstActiveObject(data
);
2505 case MUIV_Window_ActiveObject_Prev
:
2507 data
->wd_ActiveObject
= GetPrevNextActiveObject(old_activenode
,
2508 PrevObjNodeIterator
);
2509 if (NULL
== data
->wd_ActiveObject
)
2510 data
->wd_ActiveObject
= GetLastActiveObject(data
);
2514 data
->wd_ActiveObject
= (Object
*)newval
;
2519 if (data
->wd_ActiveObject
!= NULL
2520 && DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
2521 (IPTR
) data
->wd_ActiveObject
)
2522 && (_flags(data
->wd_ActiveObject
) & MADF_CANDRAW
))
2524 D(bug("Activate=%p\n", data
->wd_ActiveObject
));
2525 DoMethod(data
->wd_ActiveObject
, MUIM_GoActive
);
2526 data
->wd_Flags
|= MUIWF_OBJECTGOACTIVESENT
;
2532 * calculate real dimensions from programmer requirements.
2533 * may be overridden by user settings if MUIA_Window_ID is set.
2535 /* MUIV_Window_Height_Screen and MUIV_Window_Height_Visible
2536 * are not handled yet, as their Width couterparts.
2538 static void WindowSelectDimensions (struct MUI_WindowData
*data
)
2540 if (!data
->wd_Width
)
2542 if (data
->wd_ReqWidth
> 0)
2543 data
->wd_Width
= data
->wd_ReqWidth
;
2544 else if (data
->wd_ReqWidth
== MUIV_Window_Width_Default
)
2545 data
->wd_Width
= data
->wd_MinMax
.DefWidth
;
2546 else if (_between(MUIV_Window_Width_MinMax(100),
2548 MUIV_Window_Width_MinMax(0)))
2550 data
->wd_Width
= data
->wd_MinMax
.MinWidth
2552 * (data
->wd_MinMax
.MaxWidth
- data
->wd_MinMax
.MinWidth
);
2554 else if (_between(MUIV_Window_Width_Screen(100),
2556 MUIV_Window_Width_Screen(0)))
2558 data
->wd_Width
= data
->wd_RenderInfo
.mri_ScreenWidth
2559 * (- (data
->wd_ReqWidth
+ 200)) / 100;
2561 else if (_between(MUIV_Window_Width_Visible(100),
2563 MUIV_Window_Width_Visible(0)))
2565 data
->wd_Width
= data
->wd_RenderInfo
.mri_ScreenWidth
2566 * (- (data
->wd_ReqWidth
+ 100)) / 100;
2569 if (data
->wd_ReqHeight
> 0)
2570 data
->wd_Height
= data
->wd_ReqHeight
;
2571 else if (data
->wd_ReqHeight
== MUIV_Window_Height_Default
)
2572 data
->wd_Height
= data
->wd_MinMax
.DefHeight
;
2573 else if (_between(MUIV_Window_Height_MinMax(100),
2575 MUIV_Window_Height_MinMax(0)))
2577 data
->wd_Height
= data
->wd_MinMax
.MinHeight
2578 - data
->wd_ReqHeight
2579 * (data
->wd_MinMax
.MaxHeight
- data
->wd_MinMax
.MinHeight
);
2581 else if (_between(MUIV_Window_Height_Screen(100),
2583 MUIV_Window_Height_Screen(0)))
2588 scr
= data
->wd_RenderInfo
.mri_Screen
;
2590 height
= scr
->Height
- data
->wd_RenderInfo
.mri_BorderTop
- data
->wd_RenderInfo
.mri_BorderBottom
;
2592 /* This is new to Zune: If TopEdge Delta is requested
2593 * the screenheight doesn't cover the barlayer */
2594 if (data
->wd_Y
<= MUIV_Window_TopEdge_Delta(0))
2595 height
-= scr
->BarHeight
+ 1;
2597 data
->wd_Height
= height
* (- (data
->wd_ReqHeight
+ 200)) / 100;
2599 else if (_between(MUIV_Window_Height_Visible(100),
2601 MUIV_Window_Height_Visible(0)))
2603 data
->wd_Height
= data
->wd_RenderInfo
.mri_ScreenHeight
2604 * (- (data
->wd_ReqHeight
+ 100)) / 100;
2608 if (data
->wd_ReqWidth
== MUIV_Window_Width_Scaled
)
2609 data
->wd_Width
= data
->wd_Height
* data
->wd_MinMax
.MinWidth
2610 / data
->wd_MinMax
.MinHeight
;
2611 else if (data
->wd_ReqHeight
== MUIV_Window_Width_Scaled
)
2612 data
->wd_Height
= data
->wd_Width
* data
->wd_MinMax
.MinHeight
2613 / data
->wd_MinMax
.MinWidth
;
2615 data
->wd_Width
= CLAMP(data
->wd_Width
, data
->wd_MinMax
.MinWidth
,
2616 data
->wd_MinMax
.MaxWidth
);
2617 data
->wd_Height
= CLAMP(data
->wd_Height
, data
->wd_MinMax
.MinHeight
,
2618 data
->wd_MinMax
.MaxHeight
);
2622 /**************************************************************************
2624 **************************************************************************/
2625 IPTR
Window__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
2627 struct MUI_WindowData
*data
;
2628 struct TagItem
*tags
;
2629 struct TagItem
*tag
;
2631 obj
= (Object
*)DoSuperMethodA(cl
, obj
, (Msg
)msg
);
2635 /* Initial local instance data */
2636 data
= INST_DATA(cl
, obj
);
2638 data
->wd_MemoryPool
= CreatePool(0, 4096, 2048);
2639 if (NULL
== data
->wd_MemoryPool
)
2641 CoerceMethod(cl
, obj
, OM_DISPOSE
);
2645 data
->wd_RenderInfo
.mri_WindowObject
= obj
;
2647 NewList((struct List
*)&(data
->wd_EHList
));
2648 NewList((struct List
*)&(data
->wd_CCList
));
2649 NewList((struct List
*)&(data
->wd_CycleChain
));
2650 NewList((struct List
*)&(data
->wd_IDList
));
2652 data
->wd_CrtFlags
= WFLG_SIZEGADGET
| WFLG_DRAGBAR
| WFLG_DEPTHGADGET
2653 | WFLG_CLOSEGADGET
| WFLG_SIMPLE_REFRESH
2654 | WFLG_REPORTMOUSE
| WFLG_NEWLOOKMENUS
;
2655 data
->wd_ZoomGadget
= TRUE
;
2656 data
->wd_Events
= GetDefaultEvents();
2657 data
->wd_ActiveObject
= NULL
;
2659 data
->wd_ReqHeight
= MUIV_Window_Height_Default
;
2660 data
->wd_ReqWidth
= MUIV_Window_Width_Default
;
2661 data
->wd_RootObject
= NULL
;
2662 data
->wd_DefaultObject
= NULL
;
2664 /* alternate dimensions */
2665 /* no change in coordinates */
2667 // otigreat 02/10/2011 Commented out as this forbids
2668 // MUI-windows to behave like other windows when zoomed
2669 data->wd_AltDim.Top = MUIV_Window_AltTopEdge_NoChange;
2670 data->wd_AltDim.Left = MUIV_Window_AltLeftEdge_NoChange;
2672 /* default to min size */
2673 data
->wd_AltDim
.Width
= MUIV_Window_AltWidth_MinMax(0);
2674 data
->wd_AltDim
.Height
= MUIV_Window_AltHeight_MinMax(0);
2675 data
->wd_X
= MUIV_Window_LeftEdge_Centered
;
2676 data
->wd_Y
= MUIV_Window_TopEdge_Centered
;
2677 data
->wd_DisabledKeys
= 0L;
2678 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_FIRST
;
2680 /* parse initial taglist */
2682 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
)); )
2684 switch (tag
->ti_Tag
)
2686 case MUIA_Window_EraseArea
:
2687 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_ERASEAREA
);
2690 case MUIA_Window_ToolBox
:
2691 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_TOOLBOX
);
2694 case MUIA_Window_CloseGadget
:
2695 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_CLOSEGADGET
);
2698 case MUIA_Window_SizeGadget
:
2699 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_SIZEGADGET
);
2702 case MUIA_Window_ZoomGadget
:
2703 data
->wd_ZoomGadget
= tag
->ti_Data
;
2706 case MUIA_Window_Backdrop
:
2707 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_BACKDROP
);
2710 case MUIA_Window_Borderless
:
2711 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_BORDERLESS
);
2714 case MUIA_Window_DepthGadget
:
2715 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_DEPTHGADGET
);
2718 case MUIA_Window_DragBar
:
2719 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_DRAGBAR
);
2722 case MUIA_Window_SizeRight
:
2723 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_SIZEBRIGHT
);
2726 case MUIA_Window_Height
:
2727 data
->wd_ReqHeight
= (LONG
)tag
->ti_Data
;
2730 case MUIA_Window_Width
:
2731 data
->wd_ReqWidth
= (LONG
)tag
->ti_Data
;
2734 case MUIA_Window_ID
:
2735 set(obj
, MUIA_Window_ID
, tag
->ti_Data
);
2738 case MUIA_Window_IsSubWindow
:
2739 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_ISSUBWINDOW
);
2742 case MUIA_Window_Title
:
2743 set(obj
, MUIA_Window_Title
, tag
->ti_Data
);
2746 case MUIA_Window_ScreenTitle
:
2747 set(obj
, MUIA_Window_ScreenTitle
, tag
->ti_Data
);
2750 case MUIA_Window_Activate
:
2751 _handle_bool_tag(data
->wd_Flags
, !tag
->ti_Data
, MUIWF_DONTACTIVATE
);
2754 case MUIA_Window_DefaultObject
:
2755 set(obj
, MUIA_Window_DefaultObject
, tag
->ti_Data
);
2758 case MUIA_Window_Menustrip
:
2759 data
->wd_ChildMenustrip
= (Object
*)tag
->ti_Data
;
2762 case MUIA_Window_NoMenus
:
2763 data
->wd_NoMenus
= (BOOL
) tag
->ti_Data
;
2766 case MUIA_Window_RootObject
:
2769 CoerceMethod(cl
, obj
, OM_DISPOSE
);
2772 set(obj
, MUIA_Window_RootObject
, tag
->ti_Data
);
2775 case MUIA_Window_AltHeight
:
2776 data
->wd_AltDim
.Height
= (WORD
)tag
->ti_Data
;
2779 case MUIA_Window_AltWidth
:
2780 data
->wd_AltDim
.Width
= (WORD
)tag
->ti_Data
;
2783 case MUIA_Window_AltLeftEdge
:
2784 data
->wd_AltDim
.Left
= (WORD
)tag
->ti_Data
;
2787 case MUIA_Window_AltTopEdge
:
2788 data
->wd_AltDim
.Top
= (WORD
)tag
->ti_Data
;
2791 case MUIA_Window_AppWindow
:
2792 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_ISAPPWINDOW
);
2795 case MUIA_Window_LeftEdge
:
2796 data
->wd_X
= tag
->ti_Data
;
2799 case MUIA_Window_TopEdge
:
2800 data
->wd_Y
= tag
->ti_Data
;
2803 case MUIA_Window_UseBottomBorderScroller
:
2804 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_USEBOTTOMSCROLLER
);
2807 case MUIA_Window_UseRightBorderScroller
:
2808 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_USERIGHTSCROLLER
);
2811 case MUIA_Window_DisableKeys
:
2812 data
->wd_DisabledKeys
= tag
->ti_Data
;
2815 case MUIA_Window_RefWindow
:
2816 data
->wd_RefWindow
= (Object
*)tag
->ti_Data
;
2819 case MUIA_Window_Screen
:
2820 data
->wd_UserScreen
= (struct Screen
*)tag
->ti_Data
;
2823 case MUIA_Window_PublicScreen
:
2824 data
->wd_UserPublicScreen
= (STRPTR
)tag
->ti_Data
;
2829 /* D(bug("muimaster.library/window.c: Window Object created at 0x%lx back=%lx\n", */
2830 /* obj,data->wd_Background)); */
2835 /**************************************************************************
2837 **************************************************************************/
2838 IPTR
Window__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
2840 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
2842 /* D(bug("Window_Dispose(%p)\n", obj)); */
2844 #if 0 /* We no longer clear muiGlobalInfo() during disconnections, so
2845 this can cause problems (remove object which is already removed).
2846 Furthermore AFAIK it is not legal to dispose a window object
2847 which is still ocnnected to the application object, anyway. */
2849 if (muiGlobalInfo(obj
) && _app(obj
))
2851 /* D(bug(" Window_Dispose(%p) : calling app->OM_REMMEMBER\n", obj)); */
2852 DoMethod(_app(obj
), OM_REMMEMBER
, (IPTR
)obj
);
2856 if (data
->wd_RootObject
)
2857 MUI_DisposeObject(data
->wd_RootObject
);
2859 if (data
->wd_ChildMenustrip
)
2860 MUI_DisposeObject(data
->wd_ChildMenustrip
);
2863 FreeVec(data
->wd_Title
);
2865 if (data
->wd_ScreenTitle
)
2866 FreeVec(data
->wd_ScreenTitle
);
2868 DeletePool(data
->wd_MemoryPool
);
2870 /* D(bug(" Window_Dispose(%p) : calling supermethod\n", obj)); */
2871 return DoSuperMethodA(cl
, obj
, msg
);
2874 static ULONG
WindowOpen(struct IClass
*cl
, Object
*obj
);
2875 static ULONG
WindowClose(struct IClass
*cl
, Object
*obj
);
2877 /**************************************************************************
2879 **************************************************************************/
2880 IPTR
Window__OM_SET(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
2882 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
2883 struct TagItem
*tags
= msg
->ops_AttrList
;
2884 struct TagItem
*tag
;
2886 while ((tag
= NextTagItem(&tags
)) != NULL
)
2888 switch (tag
->ti_Tag
)
2890 case MUIA_Window_Activate
:
2891 if (data
->wd_RenderInfo
.mri_Window
)
2893 if (tag
->ti_Data
&& !(data
->wd_Flags
& MUIWF_ACTIVE
))
2895 ActivateWindow(data
->wd_RenderInfo
.mri_Window
);
2896 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_ACTIVE
);
2900 _handle_bool_tag(data
->wd_Flags
, !tag
->ti_Data
, MUIWF_DONTACTIVATE
);
2903 case MUIA_Window_ActiveObject
:
2904 /* D(bug("MUIA_Window_ActiveObject %ld (%p)\n", tag->ti_Data, tag->ti_Data)); */
2905 SetActiveObject(data
, obj
, tag
->ti_Data
);
2908 case MUIA_Window_DefaultObject
:
2909 data
->wd_DefaultObject
= (APTR
)tag
->ti_Data
;
2912 case MUIA_Window_ID
:
2913 data
->wd_ID
= tag
->ti_Data
;
2916 case MUIA_Window_IsSubWindow
:
2917 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_ISSUBWINDOW
);
2920 case MUIA_Window_Open
:
2923 if (data
->wd_Flags
& MUIWF_HIDDEN
)
2924 data
->wd_Flags
|= MUIWF_OPENONUNHIDE
;
2926 if (!(data
->wd_Flags
& MUIWF_OPENED
))
2927 WindowOpen(cl
, obj
);
2930 DoMethod(obj
, MUIM_Window_ToFront
);
2931 set(obj
, MUIA_Window_Activate
, TRUE
);
2935 if (data
->wd_Flags
& MUIWF_HIDDEN
)
2936 data
->wd_Flags
&= ~MUIWF_OPENONUNHIDE
;
2938 if (data
->wd_Flags
& MUIWF_OPENED
)
2939 WindowClose(cl
, obj
);
2942 case MUIA_ShowMe
: /* PRIVATE *abuse* of the Area's ShowMe attr */
2947 if (data
->wd_Flags
& MUIWF_HIDDEN
)
2949 data
->wd_Flags
&= ~MUIWF_HIDDEN
;
2951 if (data
->wd_Flags
& MUIWF_OPENONUNHIDE
)
2953 data
->wd_Flags
&= ~MUIWF_OPENONUNHIDE
;
2954 set(obj
, MUIA_Window_Open
, TRUE
);
2962 if (data
->wd_Flags
& MUIWF_OPENED
)
2964 data
->wd_Flags
|= MUIWF_OPENONUNHIDE
;
2966 set(obj
, MUIA_Window_Open
, FALSE
);
2969 data
->wd_Flags
|= MUIWF_HIDDEN
;
2973 case MUIA_Window_RootObject
:
2974 ChangeRootObject(data
, obj
, (Object
*)tag
->ti_Data
);
2977 case MUIA_Window_Title
:
2979 FreeVec(data
->wd_Title
);
2980 data
->wd_Title
= StrDup((STRPTR
)tag
->ti_Data
);
2981 if (data
->wd_RenderInfo
.mri_Window
)
2982 SetWindowTitles(data
->wd_RenderInfo
.mri_Window
,data
->wd_Title
, (CONST_STRPTR
)~0);
2985 case MUIA_Window_ScreenTitle
:
2986 if (data
->wd_ScreenTitle
)
2987 FreeVec(data
->wd_ScreenTitle
);
2988 data
->wd_ScreenTitle
= StrDup((STRPTR
)tag
->ti_Data
);
2989 if (data
->wd_RenderInfo
.mri_Window
)
2990 SetWindowTitles(data
->wd_RenderInfo
.mri_Window
,
2991 (CONST_STRPTR
)~0, data
->wd_ScreenTitle
);
2994 case MUIA_Window_NoMenus
:
2995 data
->wd_NoMenus
= (BOOL
) tag
->ti_Data
;
2996 if (data
->wd_RenderInfo
.mri_Window
)
2998 if (data
->wd_NoMenus
)
2999 data
->wd_RenderInfo
.mri_Window
->Flags
|= WFLG_RMBTRAP
;
3001 data
->wd_RenderInfo
.mri_Window
->Flags
&= ~WFLG_RMBTRAP
;
3005 case MUIA_Window_UseBottomBorderScroller
:
3006 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_USEBOTTOMSCROLLER
);
3009 case MUIA_Window_UseRightBorderScroller
:
3010 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_USERIGHTSCROLLER
);
3013 case MUIA_Window_DisableKeys
:
3014 data
->wd_DisabledKeys
= tag
->ti_Data
;
3017 case MUIA_Window_RefWindow
:
3018 data
->wd_RefWindow
= (Object
*)tag
->ti_Data
;
3021 case MUIA_Window_LeftEdge
:
3022 data
->wd_X
= tag
->ti_Data
;
3025 case MUIA_Window_TopEdge
:
3026 data
->wd_Y
= tag
->ti_Data
;
3029 case MUIA_Window_Width
:
3030 data
->wd_ReqWidth
= (LONG
)tag
->ti_Data
;
3031 data
->wd_Width
= 0; /* otherwise windowselectdimensions() ignores ReqWidth */
3034 case MUIA_Window_Height
:
3035 data
->wd_ReqHeight
= (LONG
)tag
->ti_Data
;
3036 data
->wd_Height
= 0;
3039 case MUIA_Window_Screen
:
3040 data
->wd_UserScreen
= (struct Screen
*)tag
->ti_Data
;
3043 case MUIA_Window_PublicScreen
:
3044 data
->wd_UserPublicScreen
= (STRPTR
)tag
->ti_Data
;
3047 case MUIA_Window_Sleep
:
3050 data
->wd_SleepCount
++;
3051 if (data
->wd_RenderInfo
.mri_Window
&& (data
->wd_SleepCount
== 1))
3055 data
->wd_RenderInfo
.mri_Window
,
3056 WA_BusyPointer
, TRUE
,
3057 WA_PointerDelay
, TRUE
,
3060 // FIXME: how to disable event handling?
3065 data
->wd_SleepCount
--;
3066 if (data
->wd_RenderInfo
.mri_Window
&& (data
->wd_SleepCount
== 0))
3068 SetWindowPointerA(data
->wd_RenderInfo
.mri_Window
, NULL
);
3076 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
3079 /**************************************************************************
3081 **************************************************************************/
3082 IPTR
Window__OM_GET(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
3084 #define STORE *(msg->opg_Storage)
3086 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3090 switch(msg
->opg_AttrID
)
3092 case MUIA_Window_Activate
:
3093 STORE
= (data
->wd_Flags
& (MUIWF_ACTIVE
| MUIWF_OPENED
)) == (MUIWF_ACTIVE
| MUIWF_OPENED
);
3096 case MUIA_Window_Window
:
3097 STORE
= (IPTR
)data
->wd_RenderInfo
.mri_Window
;
3100 case MUIA_Window_Screen
:
3101 STORE
= (IPTR
)data
->wd_RenderInfo
.mri_Screen
;
3104 case MUIA_Window_PublicScreen
:
3105 STORE
= (IPTR
)data
->wd_UserPublicScreen
;
3108 case MUIA_Window_ActiveObject
:
3109 if ((data
->wd_ActiveObject
!= NULL
)
3110 && (DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
3111 (IPTR
)data
->wd_ActiveObject
) != (IPTR
)NULL
))
3112 STORE
= (IPTR
)data
->wd_ActiveObject
;
3117 case MUIA_Window_CloseRequest
:
3121 case MUIA_Window_DefaultObject
:
3122 STORE
= (IPTR
)data
->wd_DefaultObject
;
3125 case MUIA_Window_DisableKeys
:
3126 STORE
= data
->wd_DisabledKeys
;
3129 case MUIA_Window_Height
:
3130 STORE
= (IPTR
)data
->wd_Height
;
3133 case MUIA_Window_ID
:
3134 STORE
= data
->wd_ID
;
3137 case MUIA_Window_IsSubWindow
:
3138 STORE
= (data
->wd_Flags
& MUIWF_ISSUBWINDOW
) == MUIWF_ISSUBWINDOW
;
3141 case MUIA_Window_LeftEdge
:
3142 if (data
->wd_RenderInfo
.mri_Window
)
3143 STORE
= (IPTR
)data
->wd_RenderInfo
.mri_Window
->LeftEdge
;
3148 case MUIA_Window_Open
:
3149 STORE
= (data
->wd_Flags
& MUIWF_OPENED
) == MUIWF_OPENED
;
3152 case MUIA_Window_RootObject
:
3153 STORE
= (IPTR
)data
->wd_RootObject
;
3156 case MUIA_Window_ScreenTitle
:
3157 STORE
= (IPTR
)data
->wd_ScreenTitle
;
3160 case MUIA_Window_Title
:
3161 STORE
= (IPTR
)data
->wd_Title
;
3164 case MUIA_Window_TopEdge
:
3165 if (data
->wd_RenderInfo
.mri_Window
)
3166 STORE
= (IPTR
)data
->wd_RenderInfo
.mri_Window
->TopEdge
;
3171 case MUIA_Window_Width
:
3172 STORE
= (IPTR
)data
->wd_Width
;
3175 case MUIA_Window_Menustrip
:
3176 STORE
= (IPTR
)data
->wd_ChildMenustrip
;
3179 case MUIA_Window_Sleep
:
3180 STORE
= data
->wd_SleepCount
? TRUE
: FALSE
;
3192 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
3197 * MUIM_FindUData : tests if the MUIA_UserData of the object
3198 * contains the given <udata> and returns the object pointer in this case.
3200 IPTR
Window__MUIM_FindUData(struct IClass
*cl
, Object
*obj
, struct MUIP_FindUData
*msg
)
3202 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3204 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3207 if (data
->wd_RootObject
)
3208 return DoMethodA(data
->wd_RootObject
, (Msg
)msg
);
3215 * MUIM_GetUData : This method tests if the MUIA_UserData of the object
3216 * contains the given <udata> and gets <attr> to <storage> for itself
3219 IPTR
Window__MUIM_GetUData(struct IClass
*cl
, Object
*obj
, struct MUIP_GetUData
*msg
)
3221 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3223 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3225 get(obj
, msg
->attr
, msg
->storage
);
3229 if (data
->wd_RootObject
)
3230 return DoMethodA(data
->wd_RootObject
, (Msg
)msg
);
3237 * MUIM_SetUData : This method tests if the MUIA_UserData of the object
3238 * contains the given <udata> and sets <attr> to <val> for itself in this case.
3240 IPTR
Window__MUIM_SetUData(struct IClass
*cl
, Object
*obj
, struct MUIP_SetUData
*msg
)
3242 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3244 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3245 set(obj
, msg
->attr
, msg
->val
);
3247 if (data
->wd_RootObject
)
3248 DoMethodA(data
->wd_RootObject
, (Msg
)msg
);
3255 * MUIM_SetUDataOnce : This method tests if the MUIA_UserData of the object
3256 * contains the given <udata> and sets <attr> to <val> for itself in this case.
3258 IPTR
Window__MUIM_SetUDataOnce(struct IClass
*cl
, Object
*obj
, struct MUIP_SetUDataOnce
*msg
)
3260 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3262 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3264 set(obj
, msg
->attr
, msg
->val
);
3268 if (data
->wd_RootObject
)
3269 return DoMethodA(data
->wd_RootObject
, (Msg
)msg
);
3274 /**************************************************************************
3275 Called by Application (parent) object whenever this object is added.
3277 **************************************************************************/
3278 IPTR
Window__MUIM_ConnectParent(struct IClass
*cl
, Object
*obj
,
3279 struct MUIP_ConnectParent
*msg
)
3281 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3283 if (!DoSuperMethodA(cl
,obj
,(Msg
)msg
))
3286 if (data
->wd_RootObject
)
3287 DoMethod(data
->wd_RootObject
, MUIM_ConnectParent
, (IPTR
)obj
);
3289 if (data
->wd_ChildMenustrip
)
3290 DoMethod(data
->wd_ChildMenustrip
, MUIM_ConnectParent
, (IPTR
)obj
);
3296 /**************************************************************************
3297 called by parent object
3298 **************************************************************************/
3299 IPTR
Window__MUIM_DisconnectParent(struct IClass
*cl
, Object
*obj
, struct MUIP_DisconnectParent
*msg
)
3301 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3303 /* D(bug("Window_DisconnectParent(%p) : muiGlobalInfo=%p\n", muiGlobalInfo(obj))); */
3304 if (muiGlobalInfo(obj
))
3306 /* Close the window before disconnecting all the childs */
3307 if ((data
->wd_Flags
& MUIWF_OPENED
))
3309 /* D(bug(" Window_DisconnectParent(%p) : closing window\n", muiGlobalInfo(obj))); */
3310 set(obj
, MUIA_Window_Open
, FALSE
);
3312 if (data
->wd_ChildMenustrip
)
3313 DoMethod(data
->wd_ChildMenustrip
, MUIM_DisconnectParent
, (IPTR
)obj
);
3315 if (data
->wd_RootObject
)
3316 DoMethodA(data
->wd_RootObject
, (Msg
)msg
);
3318 /* D(bug(" Window_DisconnectParent(%p) : calling supermethod\n", muiGlobalInfo(obj))); */
3319 return DoSuperMethodA(cl
,obj
,(Msg
)msg
);
3327 static void SetRootObjInnerSpacing(Object
*obj
, struct MUI_WindowData
*data
)
3329 UWORD wd_innerLeft
, wd_innerRight
, wd_innerTop
, wd_innerBottom
;
3331 if (data
->wd_CrtFlags
& WFLG_BORDERLESS
)
3340 wd_innerLeft
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_left
;
3341 wd_innerRight
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_right
;
3342 wd_innerTop
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_top
;
3343 wd_innerBottom
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_bottom
;
3346 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERLEFT
))
3348 muiAreaData(data
->wd_RootObject
)->mad_InnerLeft
= wd_innerLeft
;
3351 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERTOP
))
3353 muiAreaData(data
->wd_RootObject
)->mad_InnerTop
= wd_innerTop
;
3356 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERRIGHT
))
3358 muiAreaData(data
->wd_RootObject
)->mad_InnerRight
= wd_innerRight
;
3361 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERBOTTOM
))
3363 muiAreaData(data
->wd_RootObject
)->mad_InnerBottom
= wd_innerBottom
;
3368 * Called before window is opened or resized. It determines its bounds,
3369 * so you can call WindowSelectDimensions() to find the final dims.
3371 static void WindowMinMax(Object
*obj
, struct MUI_WindowData
*data
)
3373 SetRootObjInnerSpacing(obj
, data
);
3374 /* inquire about sizes */
3375 DoMethod(data
->wd_RootObject
, MUIM_AskMinMax
, (IPTR
)&data
->wd_MinMax
);
3376 /* D(bug("*** root minmax = %ld,%ld => %ld,%ld\n", data->wd_MinMax.MinWidth, */
3377 /* data->wd_MinMax.MinHeight, */
3378 /* data->wd_MinMax.MaxWidth, data->wd_MinMax.MaxHeight)); */
3379 __area_finish_minmax(data
->wd_RootObject
, &data
->wd_MinMax
);
3380 /* D(bug("*** root minmax2 = %ld,%ld => %ld,%ld\n", data->wd_MinMax.MinWidth, */
3381 /* data->wd_MinMax.MinHeight, */
3382 /* data->wd_MinMax.MaxWidth, data->wd_MinMax.MaxHeight)); */
3386 static void InstallBackbuffer (struct IClass
*cl
, Object
*obj
)
3388 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3390 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
3392 data
->wd_RenderInfo
.mri_BufferBM
=
3393 AllocBitMap(win
->Width
, win
->Height
, win
->RPort
->BitMap
->Depth
,
3394 0, win
->RPort
->BitMap
);
3396 if (data
->wd_RenderInfo
.mri_BufferBM
)
3398 /* D(bug("install_backbuffer : allocated bitmap %dx%dx%d with friend %p\n", */
3399 /* win->Width, win->Height, win->RPort->BitMap->Depth, win->RPort->BitMap)); */
3400 InitRastPort(&data
->wd_RenderInfo
.mri_BufferRP
);
3401 data
->wd_RenderInfo
.mri_BufferRP
.BitMap
= data
->wd_RenderInfo
.mri_BufferBM
;
3405 static void DeinstallBackbuffer (struct IClass
*cl
, Object
*obj
)
3407 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3409 if (data
->wd_RenderInfo
.mri_BufferBM
)
3411 DeinitRastPort(&data
->wd_RenderInfo
.mri_BufferRP
);
3412 FreeBitMap(data
->wd_RenderInfo
.mri_BufferBM
);
3413 data
->wd_RenderInfo
.mri_BufferBM
= NULL
;
3418 * Called after window is opened or resized.
3419 * An expose event is already queued, it will trigger
3420 * MUIM_Draw for us when going back to main loop.
3422 static void WindowShow (struct IClass
*cl
, Object
*obj
)
3424 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3425 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
3426 /* D(bug("window_show %s %d\n", __FILE__, __LINE__)); */
3428 _left(data
->wd_RootObject
) = win
->BorderLeft
;
3429 _top(data
->wd_RootObject
) = win
->BorderTop
;
3430 _width(data
->wd_RootObject
) = data
->wd_Width
;
3431 _height(data
->wd_RootObject
) = data
->wd_Height
;
3433 DoMethod(data
->wd_RootObject
, MUIM_Layout
);
3435 ShowRenderInfo(&data
->wd_RenderInfo
);
3436 /* D(bug("zune_imspec_show %s %d\n", __FILE__, __LINE__)); */
3437 zune_imspec_show(data
->wd_Background
, obj
);
3438 DoShowMethod(data
->wd_RootObject
);
3441 static ULONG
WindowOpen(struct IClass
*cl
, Object
*obj
)
3443 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3445 if (!data
->wd_RootObject
)
3448 if (!DoMethod(obj
, MUIM_Window_Setup
))
3451 /* I got display info, so calculate your display dependant data */
3452 if (!DoSetupMethod(data
->wd_RootObject
, &data
->wd_RenderInfo
))
3454 DoMethod(obj
, MUIM_Window_Cleanup
);
3458 /* inquire about sizes */
3459 WindowMinMax(obj
,data
);
3460 WindowSelectDimensions(data
);
3462 /* Decide which menustrip should be used */
3463 if (!data
->wd_ChildMenustrip
)
3464 get(_app(obj
), MUIA_Application_Menustrip
, &data
->wd_Menustrip
);
3466 data
->wd_Menustrip
= data
->wd_ChildMenustrip
;
3468 /* open window here ... */
3469 if (!DisplayWindow(obj
,data
))
3471 /* free display dependant data */
3472 data
->wd_Menustrip
= NULL
;
3473 DoMethod(data
->wd_RootObject
, MUIM_Cleanup
);
3474 DoMethod(obj
, MUIM_Window_Cleanup
);
3478 InstallBackbuffer(cl
, obj
);
3480 data
->wd_Flags
|= MUIWF_OPENED
;
3482 WindowShow(cl
, obj
);
3485 LONG left
,top
,width
,height
;
3487 left
= data
->wd_RenderInfo
.mri_Window
->BorderLeft
;
3488 top
= data
->wd_RenderInfo
.mri_Window
->BorderTop
,
3489 width
= data
->wd_RenderInfo
.mri_Window
->Width
3490 - data
->wd_RenderInfo
.mri_Window
->BorderRight
- left
;
3491 height
= data
->wd_RenderInfo
.mri_Window
->Height
3492 - data
->wd_RenderInfo
.mri_Window
->BorderBottom
- top
;
3494 /* D(bug("zune_imspec_draw %s %d\n", __FILE__, __LINE__)); */
3495 // D(bug("%d:zune_imspec_draw(%p) l=%d t=%d w=%d h=%d xo=%d yo=%d\n",
3496 // __LINE__, data->wd_Background, left, top, width,
3497 // height, left, top));
3499 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
3500 left
, top
, width
, height
, left
, top
, 0);
3503 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWOBJECT
);
3505 D(bug("MUIC_Window:windowOpen() ActiveObject=%p\n", data
->wd_ActiveObject
));
3506 if (data
->wd_OldActive
!= NULL
)
3508 set(obj
, MUIA_Window_ActiveObject
, data
->wd_OldActive
);
3514 /******************************************************************************/
3515 /******************************************************************************/
3517 static ULONG
WindowClose(struct IClass
*cl
, Object
*obj
)
3519 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3521 if (data
->wd_ActiveObject
!= NULL
)
3523 data
->wd_OldActive
= data
->wd_ActiveObject
;
3524 set(obj
, MUIA_Window_ActiveObject
, MUIV_Window_ActiveObject_None
);
3527 KillHelpBubble(data
, obj
, BUBBLEHELP_TICKER_FIRST
);
3529 /* remove from window */
3530 DoHideMethod(data
->wd_RootObject
);
3531 zune_imspec_hide(data
->wd_Background
);
3533 DeinstallBackbuffer(cl
, obj
);
3535 HideRenderInfo(&data
->wd_RenderInfo
);
3537 /* close here ... */
3538 UndisplayWindow(obj
,data
);
3540 data
->wd_Flags
&= ~MUIWF_OPENED
;
3541 data
->wd_Menustrip
= NULL
;
3543 /* free display dependant data */
3544 DoMethod(data
->wd_RootObject
, MUIM_Cleanup
);
3545 DoMethod(obj
, MUIM_Window_Cleanup
);
3549 /* calculate a new layout
3551 * see Group_ExitChange
3555 IPTR
Window__MUIM_RecalcDisplay(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_RecalcDisplay
*msg
)
3557 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3558 LONG left
,top
,width
,height
;
3560 Object
*current_obj
;
3562 if (!(data
->wd_Flags
& MUIWF_OPENED
))
3565 current_obj
= msg
->originator
;
3567 // typically originator is a group which has been added/removed a child
3568 // calculate minmax of current obj
3569 // if new minmax can accomodate current obj size, stop
3570 // else try with its parent
3571 // the resulting object will get a new layout
3572 // it currently produces some redundant AskMinMax but allows
3573 // to not always relayout the whole window
3575 D(bug("RecalcDisplay on %p\n", current_obj
));
3576 while (current_obj
!= NULL
)
3578 DoMethod(current_obj
, MUIM_AskMinMax
, (IPTR
)&muiAreaData(current_obj
)->mad_MinMax
);
3579 __area_finish_minmax(current_obj
, &muiAreaData(current_obj
)->mad_MinMax
);
3581 D(bug("size w = %d, h = %d\n", _width(current_obj
), _height(current_obj
)));
3582 D(bug("new w = %d-%d, h = %d-%d\n", _minwidth(current_obj
), _maxwidth(current_obj
),
3583 _minheight(current_obj
), _maxheight(current_obj
)));
3585 if (!_between(_minwidth(current_obj
), _width(current_obj
), _maxwidth(current_obj
))
3586 || !_between(_minheight(current_obj
), _height(current_obj
), _maxheight(current_obj
)))
3588 current_obj
= _parent(current_obj
);
3589 D(bug("RecalcDisplay, try parent %p\n", current_obj
));
3593 D(bug("found it\n"));
3599 current_obj
= data
->wd_RootObject
;
3601 WindowMinMax(obj
, data
);
3602 DoHideMethod(current_obj
);
3603 /* resize window ? */
3604 WindowSelectDimensions(data
);
3605 resized
= WindowResize(data
);
3608 /* FIXME: Should we short circuit the following
3609 * if the window size didn't change?
3614 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
3615 _left(data
->wd_RootObject
) = win
->BorderLeft
;
3616 _top(data
->wd_RootObject
) = win
->BorderTop
;
3617 _width(data
->wd_RootObject
) = data
->wd_Width
;
3618 _height(data
->wd_RootObject
) = data
->wd_Height
;
3620 DoMethod(current_obj
, MUIM_Layout
);
3621 DoShowMethod(current_obj
);
3623 if (muiGlobalInfo(obj
)->mgi_Prefs
->window_redraw
== WINDOW_REDRAW_WITHOUT_CLEAR
)
3624 MUI_Redraw(current_obj
, MADF_DRAWOBJECT
);
3627 left
= data
->wd_RenderInfo
.mri_Window
->BorderLeft
;
3628 top
= data
->wd_RenderInfo
.mri_Window
->BorderTop
;
3629 width
= data
->wd_RenderInfo
.mri_Window
->Width
3630 - data
->wd_RenderInfo
.mri_Window
->BorderRight
- left
;
3631 height
= data
->wd_RenderInfo
.mri_Window
->Height
3632 - data
->wd_RenderInfo
.mri_Window
->BorderBottom
- top
;
3634 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
3635 left
, top
, width
, height
, left
, top
, 0);
3636 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWALL
);
3639 ActivateObject(data
);
3645 /**************************************************************************
3646 MUIM_AddEventHandler
3647 **************************************************************************/
3648 IPTR
Window__MUIM_AddEventHandler(struct IClass
*cl
, Object
*obj
,
3649 struct MUIP_Window_AddEventHandler
*msg
)
3651 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3653 //D(bug("muimaster.library/window.c: Add Eventhandler %p\n", msg->ehnode));
3655 msg
->ehnode
->ehn_Priority
= msg
->ehnode
->ehn_Priority
;
3656 EnqueueByPriAndAddress((struct List
*)&data
->wd_EHList
, (struct Node
*)msg
->ehnode
);
3657 ChangeEvents(data
, GetDefaultEvents());
3661 /**************************************************************************
3662 MUIM_RemEventHandler
3663 **************************************************************************/
3664 IPTR
Window__MUIM_RemEventHandler(struct IClass
*cl
, Object
*obj
,
3665 struct MUIP_Window_RemEventHandler
*msg
)
3667 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3669 //D(bug("muimaster.library/window.c: Rem Eventhandler %p\n", msg->ehnode));
3671 Remove((struct Node
*)msg
->ehnode
);
3672 ChangeEvents(data
, GetDefaultEvents());
3676 /**************************************************************************
3677 Note that this is MUIM_Window_Setup, not MUIM_Setup
3678 **************************************************************************/
3679 IPTR
Window__MUIM_Setup(struct IClass
*cl
, Object
*obj
, Msg msg
)
3681 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3683 if (!SetupRenderInfo(obj
, data
, &data
->wd_RenderInfo
))
3686 data
->wd_Background
= zune_imspec_setup(MUII_WindowBack
, &data
->wd_RenderInfo
);
3688 if (muiGlobalInfo(obj
)->mgi_Prefs
->window_redraw
== WINDOW_REDRAW_WITH_CLEAR
)
3689 data
->wd_Flags
|= MUIWF_ERASEAREA
;
3694 /**************************************************************************
3696 **************************************************************************/
3697 IPTR
Window__MUIM_Cleanup(struct IClass
*cl
, Object
*obj
, Msg msg
)
3699 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3701 zune_imspec_cleanup(data
->wd_Background
);
3705 DeleteDragNDrop(data
->wd_dnd
);
3706 data
->wd_dnd
= NULL
;
3709 CleanupRenderInfo(obj
, data
, &data
->wd_RenderInfo
);
3714 /**************************************************************************
3715 This adds the the control char handler and also do the MUIA_CycleChain
3716 stuff. Orginal MUI does this in an other way.
3717 **************************************************************************/
3718 IPTR
Window__MUIM_AddControlCharHandler(struct IClass
*cl
, Object
*obj
,
3719 struct MUIP_Window_AddControlCharHandler
*msg
)
3721 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3722 struct ObjNode
*node
;
3724 if (msg
->ccnode
->ehn_Events
)
3726 msg
->ccnode
->ehn_Priority
= msg
->ccnode
->ehn_Priority
;
3727 Enqueue((struct List
*)&data
->wd_CCList
, (struct Node
*)msg
->ccnode
);
3729 /* Due to the lack of a better idea ... */
3730 if (muiAreaData(msg
->ccnode
->ehn_Object
)->mad_Flags
& MADF_CYCLECHAIN
)
3732 node
= AllocPooled(data
->wd_MemoryPool
, sizeof(struct ObjNode
));
3735 node
->obj
= msg
->ccnode
->ehn_Object
;
3736 AddTail((struct List
*)&data
->wd_CycleChain
,(struct Node
*)node
);
3742 /**************************************************************************
3743 MUIM_RemControlCharHandler
3744 **************************************************************************/
3745 IPTR
Window__MUIM_RemControlCharHandler(struct IClass
*cl
, Object
*obj
,
3746 struct MUIP_Window_RemControlCharHandler
*msg
)
3748 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3749 struct ObjNode
*node
= FindObjNode(&data
->wd_CycleChain
,msg
->ccnode
->ehn_Object
);
3751 if (msg
->ccnode
->ehn_Events
)
3752 Remove((struct Node
*)msg
->ccnode
);
3756 /* Remove from the chain list */
3757 Remove((struct Node
*)node
);
3758 FreePooled(data
->wd_MemoryPool
, node
, sizeof(struct ObjNode
));
3764 /**************************************************************************
3766 **************************************************************************/
3767 IPTR
Window__MUIM_DragObject(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_DragObject
*msg
)
3769 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3772 struct DragNDrop
*dnd
;
3773 struct MUI_DragImage
*di
;
3774 struct BitMapNode
*bmn
;
3776 if (!(dnd
= CreateDragNDropA(NULL
)))
3779 if (!(di
= (struct MUI_DragImage
*)DoMethod(msg
->obj
,MUIM_CreateDragImage
,-msg
->touchx
,-msg
->touchy
,msg
->flags
)))
3781 DeleteDragNDrop(dnd
);
3786 DoMethod(msg
->obj
,MUIM_DeleteDragImage
, (IPTR
)di
);
3787 DeleteDragNDrop(dnd
);
3791 if (!(bmn
= CreateBitMapNodeA(TAGLIST(
3792 GUI_BitMap
, (IPTR
)di
->bm
,
3793 GUI_LeftOffset
, di
->touchx
,
3794 GUI_TopOffset
, di
->touchy
,
3795 GUI_Width
, di
->width
,
3796 GUI_Height
, di
->height
,
3797 GUI_SourceAlpha
, !!(di
->flags
& MUIF_DRAGIMAGE_SOURCEALPHA
)))))
3799 DoMethod(msg
->obj
, MUIM_DeleteDragImage
, (IPTR
)di
);
3800 DeleteDragNDrop(dnd
);
3804 AttachBitMapNode(dnd
,bmn
);
3806 if (!PrepareDragNDrop(dnd
, data
->wd_RenderInfo
.mri_Screen
))
3808 DoMethod(msg
->obj
,MUIM_DeleteDragImage
, (IPTR
)di
);
3809 DeleteDragNDrop(dnd
);
3813 muiAreaData(msg
->obj
)->mad_Flags
|= MADF_DRAGGING
;
3815 data
->wd_DragObject
= msg
->obj
;
3817 data
->wd_DragImage
= di
;
3823 /**************************************************************************
3825 **************************************************************************/
3826 IPTR
Window__MUIM_AllocGadgetID(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_AllocGadgetID
*msg
)
3828 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3829 struct IDNode
*newnode
;
3831 newnode
= AllocPooled(data
->wd_MemoryPool
, sizeof(struct IDNode
));
3837 if (IsListEmpty((struct List
*)&data
->wd_IDList
))
3840 AddHead((struct List
*)&data
->wd_IDList
, (struct Node
*)&newnode
->node
);
3846 for (mn
= data
->wd_IDList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
3848 struct IDNode
*idn
= (struct IDNode
*)mn
;
3854 Insert((struct List
*)&data
->wd_IDList
, (struct Node
*)&newnode
->node
, (struct Node
*)mn
);
3861 /**************************************************************************
3863 **************************************************************************/
3864 IPTR
Window__MUIM_FreeGadgetID(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_FreeGadgetID
*msg
)
3866 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3869 for (mn
= data
->wd_IDList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
3871 struct IDNode
*idn
= (struct IDNode
*)mn
;
3872 if (msg
->gadgetid
== idn
->id
)
3874 Remove((struct Node
*)idn
);
3875 FreePooled(data
->wd_MemoryPool
, idn
, sizeof(struct IDNode
));
3884 /**************************************************************************
3885 MUIM_Window_GetMenuCheck
3886 **************************************************************************/
3887 IPTR
Window__MUIM_GetMenuCheck(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_GetMenuCheck
*msg
)
3890 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3892 Object
*strip
= data
->wd_ChildMenustrip
;
3894 strip
= data
->wd_Menustrip
;
3897 if (!(item
= (Object
*)DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
)))
3899 get(item
,MUIA_Menuitem_Checked
, &stat
);
3903 /**************************************************************************
3904 MUIM_Window_SetMenuCheck
3905 **************************************************************************/
3906 IPTR
Window__MUIM_SetMenuCheck(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_SetMenuCheck
*msg
)
3908 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3910 Object
*strip
= data
->wd_ChildMenustrip
;
3912 strip
= data
->wd_Menustrip
;
3915 if (!(item
= (Object
*)DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
)))
3917 set(item
,MUIA_Menuitem_Checked
,msg
->stat
);
3921 /**************************************************************************
3922 MUIM_Window_GetMenuState
3923 **************************************************************************/
3924 IPTR
Window__MUIM_GetMenuState(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_GetMenuState
*msg
)
3927 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3929 Object
*strip
= data
->wd_ChildMenustrip
;
3930 if (!strip
) strip
= data
->wd_Menustrip
;
3933 if (!(item
= (Object
*)DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
)))
3935 get(item
,MUIA_Menuitem_Enabled
, &stat
);
3939 /**************************************************************************
3940 MUIM_Window_SetMenuState
3941 **************************************************************************/
3942 IPTR
Window__MUIM_SetMenuState(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_SetMenuState
*msg
)
3944 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3946 Object
*strip
= data
->wd_ChildMenustrip
;
3948 strip
= data
->wd_Menustrip
;
3951 if (!(item
= (Object
*)DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
)))
3953 set(item
,MUIA_Menuitem_Enabled
,msg
->stat
);
3957 /**************************************************************************
3958 MUIM_Window_DrawBackground
3959 **************************************************************************/
3960 IPTR
Window__MUIM_DrawBackground(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_DrawBackground
*msg
)
3962 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3963 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
3966 // D(bug("%d:zune_imspec_draw(%p) l=%d t=%d w=%d h=%d xo=%d yo=%d\n",
3967 // __LINE__, data->wd_Background, msg->left, msg->top, msg->width,
3968 // msg->height, msg->xoffset, msg->yoffset));
3969 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
3970 msg
->left
, msg
->top
, msg
->width
, msg
->height
,
3971 msg
->xoffset
, msg
->yoffset
, 0);
3975 /**************************************************************************
3977 **************************************************************************/
3978 IPTR
Window__MUIM_ToFront(struct IClass
*cl
, Object
*obj
, Msg msg
)
3980 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3981 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
3984 WindowToFront(data
->wd_RenderInfo
.mri_Window
);
3988 /**************************************************************************
3990 **************************************************************************/
3991 IPTR
Window__MUIM_ToBack(struct IClass
*cl
, Object
*obj
, Msg msg
)
3993 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3994 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
3997 WindowToBack(data
->wd_RenderInfo
.mri_Window
);
4001 /**************************************************************************
4002 MUIM_Window_ScreenToBack
4003 **************************************************************************/
4004 IPTR
Window__MUIM_ScreenToBack(struct IClass
*cl
, Object
*obj
, Msg msg
)
4006 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4007 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
4010 ScreenToBack(data
->wd_RenderInfo
.mri_Screen
);
4014 /**************************************************************************
4015 MUIM_Window_ScreenToFront
4016 **************************************************************************/
4017 IPTR
Window__MUIM_ScreenToFront(struct IClass
*cl
, Object
*obj
, Msg msg
)
4019 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4020 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
4023 ScreenToFront(data
->wd_RenderInfo
.mri_Screen
);
4027 /**************************************************************************
4028 MUIM_Window_ActionIconify
4029 **************************************************************************/
4030 IPTR
Window__MUIM_ActionIconify(struct IClass
*cl
, Object
*obj
, Msg msg
)
4032 set(_app(obj
), MUIA_Application_Iconified
, TRUE
);
4038 /* Loads ENV: prefs, add a Window_ID chunk in the MUIW chunk, if no MUIW chunk
4039 * then create it at the same level as MUIC chunk, save prefs.
4040 * Do the same for ENVARC:
4041 * MUIW chunk layout:
4043 * 00 00 00 30 (chunk length for a single window, 0x30L big endian)
4046 * xx xx yy yy (X, Y)
4047 * ww ww hh hh (Width, Height)
4048 * ax ax ay ay (AltX, AltY)
4049 * aw aw ah ah (AltWidth, AltHeight)
4057 static void RememberWindowPosition(Object
*winobj
, ULONG id
)
4063 /* Loads ENV: prefs, remove our Window_ID chunk from the MUIW chunk, save prefs.
4064 * Do the same for ENVARC:
4065 * This function shouldnt really be in window.c, but rather in a file dealing
4066 * with prefs file stuff.
4068 static void ForgetWindowPosition(Object
*winobj
, ULONG id
)
4074 /**************************************************************************
4075 MUIM_Window_Snapshot
4076 **************************************************************************/
4077 IPTR
Window__MUIM_Snapshot(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_Snapshot
*msg
)
4079 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4080 struct windowpos winp
;
4082 winp
.id
= data
->wd_ID
;
4083 w
= data
->wd_RenderInfo
.mri_Window
;
4086 winp
.x1
= w
->LeftEdge
;
4087 winp
.y1
= w
->TopEdge
;
4088 winp
.w1
= w
->GZZWidth
;
4089 winp
.h1
= w
->GZZHeight
;
4093 winp
.h2
= 0; //to do save alt dims
4095 set(_app(obj
),MUIA_Application_SetWinPos
,&winp
);
4099 RememberWindowPosition(obj
, data
->wd_ID
);
4101 ForgetWindowPosition(obj
, data
->wd_ID
);
4105 /**************************************************************************
4106 MUIM_Window_UpdateMenu
4107 **************************************************************************/
4108 IPTR
Window__MUIM_UpdateMenu(struct IClass
*cl
, Object
*obj
, Msg msg
)
4110 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4112 struct Menu
*menu
= NULL
;
4113 struct NewMenu
*newmenu
= NULL
;
4114 APTR visinfo
= NULL
;
4115 struct Window
*win
=NULL
;
4117 if (data
->wd_Menustrip
) // only open windows can have a menustrip
4119 if ((visinfo
= GetVisualInfoA(data
->wd_RenderInfo
.mri_Screen
, NULL
)))
4121 win
= data
->wd_RenderInfo
.mri_Window
;
4122 ClearMenuStrip(win
);
4125 FreeMenus(data
->wd_Menu
);
4126 data
->wd_Menu
= NULL
;
4129 get(data
->wd_Menustrip
, MUIA_Menuitem_NewMenu
, &newmenu
);
4132 if ((menu
= CreateMenusA(newmenu
, NULL
)))
4134 struct TagItem tags
[] =
4136 { GTMN_NewLookMenus
, TRUE
},
4139 LayoutMenusA(menu
, visinfo
, tags
);
4140 data
->wd_Menu
= menu
;
4141 SetMenuStrip(win
, menu
);
4144 FreeVisualInfo(visinfo
);
4151 /**************************************************************************
4152 MUIM_Export : to export an objects "contents" to a dataspace object.
4153 **************************************************************************/
4154 static IPTR
Window__MUIM_Export(struct IClass
*cl
, Object
*obj
, struct MUIP_Export
*msg
)
4156 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4157 DoMethodA(data
->wd_RootObject
, (Msg
)msg
);
4162 /**************************************************************************
4163 MUIM_Import : to import an objects "contents" from a dataspace object.
4164 **************************************************************************/
4165 static IPTR
Window__MUIM_Import(struct IClass
*cl
, Object
*obj
, struct MUIP_Import
*msg
)
4167 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4168 DoMethodA(data
->wd_RootObject
, (Msg
)msg
);
4172 BOOPSI_DISPATCHER(IPTR
, Window_Dispatcher
, cl
, obj
, msg
)
4174 switch (msg
->MethodID
)
4176 case OM_NEW
: return Window__OM_NEW(cl
, obj
, (struct opSet
*) msg
);
4177 case OM_DISPOSE
: return Window__OM_DISPOSE(cl
, obj
, msg
);
4178 case OM_SET
: return Window__OM_SET(cl
, obj
, (struct opSet
*)msg
);
4179 case OM_GET
: return Window__OM_GET(cl
, obj
, (struct opGet
*)msg
);
4180 case MUIM_FindUData
: return Window__MUIM_FindUData(cl
, obj
, (struct MUIP_FindUData
*)msg
);
4181 case MUIM_GetUData
: return Window__MUIM_GetUData(cl
, obj
, (struct MUIP_GetUData
*)msg
);
4182 case MUIM_SetUData
: return Window__MUIM_SetUData(cl
, obj
, (struct MUIP_SetUData
*)msg
);
4183 case MUIM_SetUDataOnce
: return Window__MUIM_SetUDataOnce(cl
, obj
, (struct MUIP_SetUDataOnce
*)msg
);
4184 case MUIM_Window_AddEventHandler
: return Window__MUIM_AddEventHandler(cl
, obj
, (APTR
)msg
);
4185 case MUIM_Window_RemEventHandler
: return Window__MUIM_RemEventHandler(cl
, obj
, (APTR
)msg
);
4186 case MUIM_ConnectParent
: return Window__MUIM_ConnectParent(cl
, obj
, (APTR
)msg
);
4187 case MUIM_DisconnectParent
: return Window__MUIM_DisconnectParent(cl
, obj
, (APTR
)msg
);
4188 case MUIM_Window_RecalcDisplay
: return Window__MUIM_RecalcDisplay(cl
, obj
, (APTR
)msg
);
4189 case MUIM_Window_Setup
: return Window__MUIM_Setup(cl
, obj
, (APTR
)msg
);
4190 case MUIM_Window_Cleanup
: return Window__MUIM_Cleanup(cl
, obj
, (APTR
)msg
);
4191 case MUIM_Window_AddControlCharHandler
: return Window__MUIM_AddControlCharHandler(cl
, obj
, (APTR
)msg
);
4192 case MUIM_Window_RemControlCharHandler
: return Window__MUIM_RemControlCharHandler(cl
, obj
, (APTR
)msg
);
4193 case MUIM_Window_DragObject
: return Window__MUIM_DragObject(cl
, obj
, (APTR
)msg
);
4194 case MUIM_Window_AllocGadgetID
: return Window__MUIM_AllocGadgetID(cl
, obj
, (APTR
)msg
);
4195 case MUIM_Window_FreeGadgetID
: return Window__MUIM_FreeGadgetID(cl
, obj
, (APTR
)msg
);
4196 case MUIM_Window_GetMenuCheck
: return Window__MUIM_GetMenuCheck(cl
, obj
, (APTR
)msg
);
4197 case MUIM_Window_SetMenuCheck
: return Window__MUIM_SetMenuCheck(cl
, obj
, (APTR
)msg
);
4198 case MUIM_Window_GetMenuState
: return Window__MUIM_GetMenuState(cl
, obj
, (APTR
)msg
);
4199 case MUIM_Window_SetMenuState
: return Window__MUIM_SetMenuState(cl
, obj
, (APTR
)msg
);
4200 case MUIM_Window_DrawBackground
: return Window__MUIM_DrawBackground(cl
, obj
, (APTR
)msg
);
4201 case MUIM_Window_ToFront
: return Window__MUIM_ToFront(cl
, obj
, (APTR
)msg
);
4202 case MUIM_Window_ToBack
: return Window__MUIM_ToBack(cl
, obj
, (APTR
)msg
);
4203 case MUIM_Window_ScreenToFront
: return Window__MUIM_ScreenToFront(cl
, obj
, (APTR
)msg
);
4204 case MUIM_Window_ScreenToBack
: return Window__MUIM_ScreenToBack(cl
, obj
, (APTR
)msg
);
4205 case MUIM_Window_ActionIconify
: return Window__MUIM_ActionIconify(cl
, obj
, (APTR
)msg
);
4206 case MUIM_Window_Snapshot
: return Window__MUIM_Snapshot(cl
, obj
, (APTR
)msg
);
4207 case MUIM_Window_UpdateMenu
: return Window__MUIM_UpdateMenu(cl
, obj
, (APTR
)msg
);
4208 case MUIM_Export
: return Window__MUIM_Export(cl
, obj
, (APTR
)msg
);
4209 case MUIM_Import
: return Window__MUIM_Import(cl
, obj
, (APTR
)msg
);
4212 return DoSuperMethodA(cl
, obj
, msg
);
4214 BOOPSI_DISPATCHER_END
4220 const struct __MUIBuiltinClass _MUI_Window_desc
= {
4223 sizeof(struct MUI_WindowData
),
4224 (void*)Window_Dispatcher