2 Copyright © 2011, The AROS Development Team. All rights reserved.
5 Desc: Workbook Application Class
10 #include <aros/debug.h>
15 #include <proto/dos.h>
16 #include <proto/exec.h>
17 #include <proto/intuition.h>
18 #include <proto/utility.h>
19 #include <proto/gadtools.h>
20 #include <proto/workbench.h>
21 #include <proto/graphics.h>
23 #include <intuition/classusr.h>
24 #include <libraries/gadtools.h>
25 #include <workbench/handler.h>
27 #include "workbook_intern.h"
28 #include "workbook_menu.h"
32 struct MsgPort
*WinPort
;
33 ULONG WinMask
; /* Mask of our port(s) */
34 struct MsgPort
*AppPort
;
35 ULONG AppMask
; /* Mask of our port(s) */
36 Object
*Root
; /* Background 'root' window */
37 struct MinList Windows
; /* Subwindows */
40 static void wbOpenDrawer(Class
*cl
, Object
*obj
, CONST_STRPTR path
)
42 struct WorkbookBase
*wb
= (APTR
)cl
->cl_UserData
;
43 struct wbApp
*my
= INST_DATA(cl
, obj
);
46 win
= NewObject(WBWindow
, NULL
,
47 WBWA_UserPort
, my
->WinPort
,
52 DoMethod(obj
, OM_ADDMEMBER
, win
);
56 static IPTR
WBAppNew(Class
*cl
, Object
*obj
, struct opSet
*ops
)
58 struct WorkbookBase
*wb
= (APTR
)cl
->cl_UserData
;
62 rc
= DoSuperMethodA(cl
, obj
, (Msg
)ops
);
66 my
= INST_DATA(cl
, rc
);
68 NEWLIST(&my
->Windows
);
70 /* Create our Workbench message port */
71 my
->AppPort
= CreatePort(NULL
, 0);
73 if (my
->AppPort
== NULL
) {
74 DoSuperMethod(cl
, (Object
*)rc
, OM_DISPOSE
);
78 /* Create our Window message port */
79 my
->WinPort
= CreatePort(NULL
, 0);
81 if (my
->WinPort
== NULL
) {
82 DeleteMsgPort(my
->AppPort
);
83 DoSuperMethod(cl
, (Object
*)rc
, OM_DISPOSE
);
87 my
->AppMask
|= (1UL << my
->AppPort
->mp_SigBit
);
88 my
->WinMask
|= (1UL << my
->WinPort
->mp_SigBit
);
90 /* Create our root window */
91 my
->Root
= NewObject(WBWindow
, NULL
,
93 WBWA_UserPort
, my
->WinPort
,
96 if (my
->Root
== NULL
) {
97 DeleteMsgPort(my
->WinPort
);
98 DeleteMsgPort(my
->AppPort
);
99 DoSuperMethod(cl
, (Object
*)rc
, OM_DISPOSE
);
107 static IPTR
WBAppDispose(Class
*cl
, Object
*obj
, Msg msg
)
109 struct WorkbookBase
*wb
= (APTR
)cl
->cl_UserData
;
110 struct wbApp
*my
= INST_DATA(cl
, obj
);
111 Object
*tstate
= (Object
*)my
->Windows
.mlh_Head
;
114 /* Get rid of the subwindows */
115 while ((tmp
= NextObject(&tstate
))) {
116 DoMethod(tmp
, OM_REMOVE
);
120 /* Get rid of the main window */
121 DisposeObject(my
->Root
);
123 DeleteMsgPort(my
->AppPort
);
124 DeleteMsgPort(my
->WinPort
);
126 return DoSuperMethodA(cl
, obj
, msg
);
130 static IPTR
WBAppAddMember(Class
*cl
, Object
*obj
, struct opMember
*opm
)
132 struct wbApp
*my
= INST_DATA(cl
, obj
);
134 return DoMethod(opm
->opam_Object
, OM_ADDTAIL
, &my
->Windows
);
138 static IPTR
WBAppRemMember(Class
*cl
, Object
*obj
, struct opMember
*opm
)
140 return DoMethod(opm
->opam_Object
, OM_REMOVE
);
144 static Object
*wbLookupWindow(Class
*cl
, Object
*obj
, struct Window
*win
)
146 struct WorkbookBase
*wb
= (APTR
)cl
->cl_UserData
;
147 struct wbApp
*my
= INST_DATA(cl
, obj
);
148 Object
*ostate
= (Object
*)my
->Windows
.mlh_Head
;
150 struct Window
*match
= NULL
;
152 /* Is it the root window? */
153 GetAttr(WBWA_Window
, my
->Root
, (IPTR
*)&match
);
157 while ((owin
= NextObject(&ostate
))) {
159 GetAttr(WBWA_Window
, owin
, (IPTR
*)&match
);
167 static void wbRefreshWindow(Class
*cl
, Object
*obj
, struct Window
*win
)
171 if ((owin
= wbLookupWindow(cl
, obj
, win
))) {
172 DoMethod(owin
, WBWM_REFRESH
);
176 static void wbNewSizeWindow(Class
*cl
, Object
*obj
, struct Window
*win
)
180 if ((owin
= wbLookupWindow(cl
, obj
, win
))) {
181 DoMethod(owin
, WBWM_NEWSIZE
);
185 static void wbCloseWindow(Class
*cl
, Object
*obj
, struct Window
*win
)
187 struct WorkbookBase
*wb
= (APTR
)cl
->cl_UserData
;
190 if ((owin
= wbLookupWindow(cl
, obj
, win
))) {
191 DoMethod(obj
, OM_REMMEMBER
, owin
);
196 static BOOL
wbMenuPick(Class
*cl
, Object
*obj
, struct Window
*win
, UWORD menuNumber
)
198 struct WorkbookBase
*wb
= (APTR
)cl
->cl_UserData
;
200 struct MenuItem
*item
;
203 owin
= wbLookupWindow(cl
, obj
, win
);
205 D(bug("Menu: %x\n", menuNumber
));
206 while (menuNumber
!= MENUNULL
) {
207 BOOL handled
= FALSE
;
209 item
= ItemAddress(win
->MenuStrip
, menuNumber
);
211 /* Let the window have first opportunity */
213 handled
= DoMethod(owin
, WBWM_MENUPICK
, item
, menuNumber
);
216 switch (WBMENU_ITEM_ID(item
)) {
217 case WBMENU_ID(WBMENU_WB_QUIT
):
220 case WBMENU_ID(WBMENU_WB_SHUTDOWN
):
221 /* TODO: Ask if the user wants a shutdown or reboot */
222 ShutdownA(SD_ACTION_POWEROFF
);
223 /* Can't power off. Try to reboot. */
224 ShutdownA(SD_ACTION_COLDREBOOT
);
229 menuNumber
= item
->NextSelect
;
235 static void wbIntuiTick(Class
*cl
, Object
*obj
, struct Window
*win
)
239 if ((owin
= wbLookupWindow(cl
, obj
, win
))) {
240 DoMethod(owin
, WBWM_INTUITICK
);
244 static void wbHideAllWindows(Class
*cl
, Object
*obj
)
246 struct WorkbookBase
*wb
= (APTR
)cl
->cl_UserData
;
247 struct wbApp
*my
= INST_DATA(cl
, obj
);
248 Object
*ostate
= (Object
*)my
->Windows
.mlh_Head
;
251 while ((owin
= NextObject(&ostate
))) {
252 DoMethod(owin
, WBWM_HIDE
);
256 static void wbShowAllWindows(Class
*cl
, Object
*obj
)
258 struct WorkbookBase
*wb
= (APTR
)cl
->cl_UserData
;
259 struct wbApp
*my
= INST_DATA(cl
, obj
);
260 Object
*ostate
= (Object
*)my
->Windows
.mlh_Head
;
263 while ((owin
= NextObject(&ostate
))) {
264 DoMethod(owin
, WBWM_SHOW
);
268 static void wbCloseAllWindows(Class
*cl
, Object
*obj
)
270 struct WorkbookBase
*wb
= (APTR
)cl
->cl_UserData
;
271 struct wbApp
*my
= INST_DATA(cl
, obj
);
272 Object
*ostate
= (Object
*)my
->Windows
.mlh_Head
;
275 while ((owin
= NextObject(&ostate
))) {
276 DoMethod(obj
, OM_REMMEMBER
, owin
);
281 // WBAM_WORKBENCH - Register and handle all workbench events
282 static IPTR
WBAppWorkbench(Class
*cl
, Object
*obj
, Msg msg
)
284 struct WorkbookBase
*wb
= (APTR
)cl
->cl_UserData
;
285 struct wbApp
*my
= INST_DATA(cl
, obj
);
290 if (RegisterWorkbench(my
->AppPort
)) {
294 mask
= Wait(my
->AppMask
| my
->WinMask
);
296 if (mask
& my
->AppMask
) {
297 struct WBHandlerMessage
*wbhm
;
298 wbhm
= (APTR
)GetMsg(my
->AppPort
);
300 switch (wbhm
->wbhm_Type
) {
302 /* Show all windows */
303 wbShowAllWindows(cl
, obj
);
306 /* Hide all windows */
307 wbHideAllWindows(cl
, obj
);
311 wbOpenDrawer(cl
, obj
, wbhm
->wbhm_Data
.Open
.Name
);
313 case WBHM_TYPE_UPDATE
:
314 /* Refresh an open window/object */
317 ReplyMsg((APTR
)wbhm
);
320 if (mask
& my
->WinMask
) {
321 struct IntuiMessage
*im
;
323 im
= GT_GetIMsg(my
->WinPort
);
325 D(bug("im=%p, Class=%d, Code=%d\n", im
, im
->Class
, im
->Code
));
327 case IDCMP_CLOSEWINDOW
:
328 /* Dispose the window */
329 wbCloseWindow(cl
, obj
, im
->IDCMPWindow
);
331 case IDCMP_REFRESHWINDOW
:
332 /* call WBWM_REFRESH on the window */
333 wbRefreshWindow(cl
, obj
, im
->IDCMPWindow
);
336 /* call WBWM_NEWSIZE on the window */
337 wbNewSizeWindow(cl
, obj
, im
->IDCMPWindow
);
340 done
= wbMenuPick(cl
, obj
, im
->IDCMPWindow
, im
->Code
);
342 case IDCMP_INTUITICKS
:
343 wbIntuiTick(cl
, obj
, im
->IDCMPWindow
);
351 wbCloseAllWindows(cl
, obj
);
353 UnregisterWorkbench(my
->AppPort
);
359 static IPTR
dispatcher(Class
*cl
, Object
*obj
, Msg msg
)
363 switch (msg
->MethodID
) {
364 case OM_NEW
: rc
= WBAppNew(cl
, obj
, (APTR
)msg
); break;
365 case OM_DISPOSE
: rc
= WBAppDispose(cl
, obj
, (APTR
)msg
); break;
366 case OM_ADDMEMBER
: rc
= WBAppAddMember(cl
, obj
, (APTR
)msg
); break;
367 case OM_REMMEMBER
: rc
= WBAppRemMember(cl
, obj
, (APTR
)msg
); break;
368 case WBAM_WORKBENCH
:rc
= WBAppWorkbench(cl
, obj
, (APTR
)msg
); break;
369 default: rc
= DoSuperMethodA(cl
, obj
, msg
); break;
375 Class
*WBApp_MakeClass(struct WorkbookBase
*wb
)
379 cl
= MakeClass( NULL
, "rootclass", NULL
,
380 sizeof(struct wbApp
),
383 cl
->cl_Dispatcher
.h_Entry
= HookEntry
;
384 cl
->cl_Dispatcher
.h_SubEntry
= dispatcher
;
385 cl
->cl_Dispatcher
.h_Data
= NULL
;
386 cl
->cl_UserData
= (IPTR
)wb
;