2 Copyright © 2011, Thore Böckelmann. All rights reserved.
3 Copyright © 2012, The AROS Development Team. All rights reserved.
8 #include <proto/exec.h>
10 #include <proto/intuition.h>
11 #include <proto/muimaster.h>
12 #include <proto/icon.h>
13 #include <proto/utility.h>
14 #include <proto/alib.h>
16 #include <libraries/mui.h>
17 #include <mui/Rawimage_mcc.h>
18 #include <workbench/icon.h>
20 #include "Aboutbox_mcc.h"
21 #include "Aboutbox_private.h"
26 #ifndef ICONDRAWA_Transparency
27 #define ICONDRAWA_Transparency TAG_IGNORE
31 #define MAX(a,b) ((a)>(b)?(a):(b))
35 #define DtpicObject MUIOBJMACRO_START(MUIC_Dtpic)
38 struct MUI_CustomClass
*icon_mcc
;
40 /* ------------------------------------------------------------------------- */
42 static BOOL
FileExists(CONST_STRPTR filename
)
51 BPTR lock
= Lock(filename
, ACCESS_READ
);
54 struct FileInfoBlock
*fib
= AllocDosObject(DOS_FIB
, NULL
);
57 BOOL ex
= Examine(lock
, fib
);
60 if (fib
->fib_DirEntryType
< 0) // File
65 FreeDosObject(DOS_FIB
, fib
);
72 static void clearExpandStr(struct ExpandString
*es
)
74 if(es
->string
!= NULL
)
78 static void appendExpandStr(struct ExpandString
*es
, const char *append
)
80 // add one for the terminating NUL character
81 ULONG length
= strlen(append
)+1;
83 if(es
->string
== NULL
|| strlen(es
->string
)+length
> es
->size
)
88 newSize
= es
->size
+ MAX(length
, 128);
90 if((newString
= AllocVec(newSize
, MEMF_ANY
)) != NULL
)
92 if(es
->string
!= NULL
)
94 strlcpy(newString
, es
->string
, newSize
);
102 es
->string
= newString
;
107 if(es
->string
!= NULL
)
109 strlcat(es
->string
, append
, es
->size
);
113 static void freeExpandString(struct ExpandString
*es
)
115 if(es
->string
!= NULL
)
122 static char *BuildAppInfo(struct IClass
*cl
, Object
*obj
)
124 struct Data
*data
= INST_DATA(cl
, obj
);
127 clearExpandStr(&data
->appInfo
);
129 if((info
= (char *)XGET(_app(obj
), MUIA_Application_Title
)) != NULL
)
131 appendExpandStr(&data
->appInfo
, "\033b");
132 appendExpandStr(&data
->appInfo
, info
);
133 appendExpandStr(&data
->appInfo
, "\033n\n");
135 if((info
= (char *)XGET(_app(obj
), MUIA_Application_Description
)) != NULL
)
137 appendExpandStr(&data
->appInfo
, info
);
138 appendExpandStr(&data
->appInfo
, "\n");
140 if((info
= (char *)XGET(_app(obj
), MUIA_Application_Version
)) != NULL
)
142 // skip the version cookie
143 if(strncmp(info
, "$VER: ", 6) == 0)
145 appendExpandStr(&data
->appInfo
, "\n");
146 appendExpandStr(&data
->appInfo
, info
);
147 appendExpandStr(&data
->appInfo
, "\n");
149 if((info
= (char *)XGET(_app(obj
), MUIA_Application_Copyright
)) != NULL
)
151 appendExpandStr(&data
->appInfo
, "\nCopyright ");
152 appendExpandStr(&data
->appInfo
, info
);
153 appendExpandStr(&data
->appInfo
, "\n");
156 return data
->appInfo
.string
;
159 static char *ParseCredits(struct IClass
*cl
, Object
*obj
)
161 struct Data
*data
= INST_DATA(cl
, obj
);
162 const char *credits
= data
->credits
;
164 enum { ps_Text
, ps_Placeholder
} state
;
168 clearExpandStr(&data
->parsedCredits
);
169 appendExpandStr(&data
->parsedCredits
, "\n");
171 // set up a trailing NUL for single characters
174 while((c
[0] = *credits
++) != '\0')
183 state
= ps_Placeholder
;
187 appendExpandStr(&data
->parsedCredits
, " ");
191 appendExpandStr(&data
->parsedCredits
, c
);
202 appendExpandStr(&data
->parsedCredits
, c
);
206 appendExpandStr(&data
->parsedCredits
, "Acknowledgements:");
210 appendExpandStr(&data
->parsedCredits
, "Documentation:");
214 appendExpandStr(&data
->parsedCredits
, "Graphics:");
218 appendExpandStr(&data
->parsedCredits
, "Icons:");
222 appendExpandStr(&data
->parsedCredits
, "Icon:");
226 appendExpandStr(&data
->parsedCredits
, "Translations:");
230 appendExpandStr(&data
->parsedCredits
, "Proofreading:");
234 appendExpandStr(&data
->parsedCredits
, "Music:");
238 appendExpandStr(&data
->parsedCredits
, "Programming:");
242 appendExpandStr(&data
->parsedCredits
, "Additional programming:");
246 appendExpandStr(&data
->parsedCredits
, "Sound effects:");
250 appendExpandStr(&data
->parsedCredits
, "Thanks to:");
254 appendExpandStr(&data
->parsedCredits
, "Special thanks to:");
258 appendExpandStr(&data
->parsedCredits
, "Web support:");
262 appendExpandStr(&data
->parsedCredits
, "Disclaimer:");
266 appendExpandStr(&data
->parsedCredits
, "License:");
270 appendExpandStr(&data
->parsedCredits
, c
);
280 return data
->parsedCredits
.string
;
283 /* ------------------------------------------------------------------------- */
285 #if !defined(__AROS__) && (defined(__VBCC__) || defined(NO_INLINE_STDARG))
286 #if defined(_M68000) || defined(__M68000) || defined(__mc68000)
288 // FIXME: is this good for AROS?
290 struct DiskObject
*GetIconTags(MY_CONST_STRPTR name
, ... )
292 return GetIconTagList(name
, (struct TagItem
*)(&name
+1));
295 BOOL
GetIconRectangle(struct RastPort
*rp
, CONST
struct DiskObject
*icon
, CONST STRPTR label
, struct Rectangle
*rectangle
, ...)
297 return GetIconRectangleA(rp
, icon
, label
, rectangle
, (struct TagItem
*)(&rectangle
+1));
300 VOID
DrawIconState(struct RastPort
*rp
,CONST
struct DiskObject
*icon
,CONST STRPTR label
,LONG leftEdge
,LONG topEdge
,ULONG state
,...)
302 DrawIconStateA(rp
, icon
, label
, leftEdge
, topEdge
, state
, (struct TagItem
*)(&state
+1));
308 /******************************************************************************/
310 #define MUIB_Icon (TAG_USER | 0x00000300)
312 /*** Attributes *************************************************************/
313 #define MUIA_Icon_DiskObject (MUIB_Icon | 0x00000000) /* I-- struct DiskObject * */
314 #define MUIA_Icon_File (MUIB_Icon | 0x00000001) /* I-- CONST_STRPTR */
315 #define MUIA_Icon_Screen (MUIB_Icon | 0x00000002) /* I-- struct Screen * */
317 IPTR
Icon__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
319 struct DiskObject
*icon
= NULL
;
321 struct Screen
*screen
= NULL
;
322 const struct TagItem
*tstate
= msg
->ops_AttrList
;
325 while ((tag
= NextTagItem(&tstate
)) != NULL
)
329 case MUIA_Icon_DiskObject
:
330 icon
= (struct DiskObject
*)tag
->ti_Data
;
334 file
= (STRPTR
)tag
->ti_Data
;
337 case MUIA_Icon_Screen
:
338 screen
= (struct Screen
*)tag
->ti_Data
;
343 if(icon
== NULL
&& file
== NULL
)
344 goto error
; /* Must specify one */
345 if(icon
!= NULL
&& file
!= NULL
)
346 goto error
; /* Cannot specify both */
348 if(icon
== NULL
&& file
!= NULL
)
350 if((icon
= GetIconTags(file
, ICONGETA_Screen
, screen
,
355 if((obj
= (Object
*)DoSuperNewTags(cl
, obj
, NULL
,
357 TAG_MORE
, msg
->ops_AttrList
)) != NULL
)
359 struct Icon_Data
*data
= INST_DATA(cl
, obj
);
365 FreeDiskObject(icon
);
375 IPTR
Icon__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
377 struct Icon_Data
*data
= INST_DATA(cl
, obj
);
379 if(data
->icon
!= NULL
)
380 FreeDiskObject(data
->icon
);
382 return DoSuperMethodA(cl
,obj
,msg
);
385 IPTR
Icon__MUIM_AskMinMax(struct IClass
*cl
, Object
*obj
, struct MUIP_AskMinMax
*msg
)
387 struct Icon_Data
*data
= INST_DATA(cl
, obj
);
388 struct Rectangle rect
;
391 ret
= DoSuperMethodA(cl
, obj
, (Msg
)msg
);
393 memset(&rect
, 0, sizeof(rect
));
394 if(GetIconRectangle(_rp(obj
), data
->icon
, NULL
, &rect
, ICONDRAWA_Borderless
, TRUE
,
395 ICONDRAWA_Frameless
, TRUE
,
398 LONG width
= rect
.MaxX
- rect
.MinX
+ 1;
399 LONG height
= rect
.MaxY
- rect
.MinY
+ 1;
401 msg
->MinMaxInfo
->MinWidth
+= width
;
402 msg
->MinMaxInfo
->DefWidth
+= width
;
403 msg
->MinMaxInfo
->MaxWidth
+= width
;
405 msg
->MinMaxInfo
->MinHeight
+= height
;
406 msg
->MinMaxInfo
->DefHeight
+= height
;
407 msg
->MinMaxInfo
->MaxHeight
+= height
;
413 IPTR
Icon__MUIM_Draw(struct IClass
*cl
, Object
*obj
, struct MUIP_Draw
*msg
)
415 struct Icon_Data
*data
= INST_DATA(cl
, obj
);
418 ret
= DoSuperMethodA(cl
, obj
, (Msg
)msg
);
420 if(msg
->flags
& MADF_DRAWOBJECT
)
422 DrawIconState(_rp(obj
), data
->icon
, NULL
, _mleft(obj
), _mtop(obj
), IDS_NORMAL
, ICONDRAWA_Borderless
, TRUE
,
423 ICONDRAWA_Frameless
, TRUE
,
424 ICONDRAWA_EraseBackground
, FALSE
,
425 ICONDRAWA_Transparency
, 255,
432 /* ------------------------------------------------------------------------- */
434 IPTR
Aboutbox__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
436 const struct TagItem
*tstate
= msg
->ops_AttrList
;
444 if((obj
= (Object
*)DoSuperNewTags(cl
, obj
, NULL
,
445 MUIA_Window_ID
, MAKE_ID('A','B','O','X'),
446 MUIA_Window_LeftEdge
, MUIV_Window_LeftEdge_Centered
,
447 MUIA_Window_TopEdge
, MUIV_Window_TopEdge_Centered
,
448 // MUIA_Window_Width , MUIV_Window_Width_MinMax(0),
449 // MUIA_Window_Height , MUIV_Window_Height_MinMax(0),
450 MUIA_Window_Title
, "Aboutbox",
451 MUIA_Window_NoMenus
, TRUE
,
453 // FIXME: following don't exist in AROS
454 MUIA_Window_ShowAbout
, FALSE
,
455 MUIA_Window_ShowIconify
, FALSE
,
456 MUIA_Window_ShowJump
, FALSE
,
457 MUIA_Window_ShowPopup
, FALSE
,
458 MUIA_Window_ShowPrefs
, FALSE
,
459 MUIA_Window_ShowSnapshot
, FALSE
,
461 MUIA_Window_UseRightBorderScroller
, TRUE
,
462 MUIA_Window_CloseGadget
, FALSE
,
463 MUIA_Window_SizeRight
, TRUE
,
464 WindowContents
, VGroup
,
466 Child
, logoGroup
= VGroup
,
469 Child
, ScrollgroupObject
,
471 MUIA_Scrollgroup_FreeHoriz
, FALSE
,
472 MUIA_Scrollgroup_UseWinBorder
, TRUE
,
473 MUIA_Scrollgroup_Contents
, VGroupV
,
475 Child
, appInfoText
= TextObject
, End
,
476 Child
, RectangleObject
, MUIA_Rectangle_HBar
, TRUE
, End
,
477 Child
, creditsText
= TextObject
, End
,
483 Child
, okButton
= SimpleButton("_Ok"),
487 TAG_MORE
, msg
->ops_AttrList
)) != NULL
)
489 struct Data
*data
= INST_DATA(cl
, obj
);
491 data
->logoGroup
= logoGroup
;
492 data
->appInfoText
= appInfoText
;
493 data
->creditsText
= creditsText
;
494 data
->fallbackMode
= MUIV_Aboutbox_LogoFallbackMode_Auto
;
496 while ((tag
= NextTagItem(&tstate
)) != NULL
)
500 case MUIA_Aboutbox_Credits
:
501 data
->credits
= (CONST_STRPTR
)tag
->ti_Data
;
504 case MUIA_Aboutbox_Build
:
505 data
->build
= (CONST_STRPTR
)tag
->ti_Data
;
508 case MUIA_Aboutbox_LogoFallbackMode
:
509 data
->fallbackMode
= tag
->ti_Data
;
512 case MUIA_Aboutbox_LogoFile
:
513 data
->logoFile
= (CONST_STRPTR
)tag
->ti_Data
;
516 case MUIA_Aboutbox_LogoData
:
517 data
->logoData
= (CONST_APTR
)tag
->ti_Data
;
522 DoMethod(obj
, MUIM_Notify
, MUIA_Window_CloseRequest
, TRUE
, MUIV_Notify_Application
, 6, MUIM_Application_PushMethod
, obj
, 3, MUIM_Set
, MUIA_Window_Open
, FALSE
);
523 DoMethod(okButton
, MUIM_Notify
, MUIA_Pressed
, FALSE
, MUIV_Notify_Application
, 6, MUIM_Application_PushMethod
, obj
, 3, MUIM_Set
, MUIA_Window_Open
, FALSE
);
530 IPTR
Aboutbox__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
532 struct Data
*data
= INST_DATA(cl
, obj
);
534 freeExpandString(&data
->appInfo
);
535 freeExpandString(&data
->parsedCredits
);
537 return DoSuperMethodA(cl
,obj
,msg
);
541 static Object
*BuildLogo(struct IClass
*cl
, Object
*obj
)
543 struct Data
*data
= INST_DATA(cl
, obj
);
544 ULONG fallbackMode
= data
->fallbackMode
;
547 while(fallbackMode
!= MUIV_Aboutbox_LogoFallbackMode_NoLogo
&& logo
== NULL
)
551 mode
= (fallbackMode
>> 24) & 0xff;
558 // try to get the program name the simple way first
559 if(GetProgramName(data
->progName
, sizeof(data
->progName
)) == DOSFALSE
)
561 // no CLI structure, construct the name as "PROGDIR:<task name>"
562 struct Task
*me
= FindTask(NULL
);
564 strlcpy(data
->progName
, "PROGDIR:", sizeof(data
->progName
));
565 AddPart(data
->progName
, me
->tc_Node
.ln_Name
, sizeof(data
->progName
));
567 else if(strnicmp(data
->progName
, "APPDIR:", 7) == 0)
571 // an APPDIR: path, construct the name as "PROGDIR:<file part of app path>"
572 strlcpy(tempPath
, "PROGDIR:", sizeof(tempPath
));
573 AddPart(tempPath
, FilePart(data
->progName
), sizeof(tempPath
));
574 strlcpy(data
->progName
, tempPath
, sizeof(data
->progName
));
577 logo
= NewObject(icon_mcc
->mcc_Class
, NULL
, MUIA_Icon_File
, data
->progName
,
578 MUIA_Icon_Screen
, XGET(obj
, MUIA_Window_Screen
),
585 if(data
->logoFile
!= NULL
&& FileExists(data
->logoFile
))
588 MUIA_Dtpic_Name
, data
->logoFile
,
596 if(data
->logoData
!= NULL
)
598 logo
= RawimageObject
,
599 MUIA_Rawimage_Data
, data
->logoData
,
606 fallbackMode
= MUIV_Aboutbox_LogoFallbackMode_NoLogo
;
614 IPTR
Aboutbox__MUIM_Window_Setup(struct IClass
*cl
, Object
*obj
, Msg msg
)
618 if((ret
= DoSuperMethodA(cl
, obj
, (Msg
)msg
)))
620 struct Data
*data
= INST_DATA(cl
, obj
);
622 if((data
->logo
= BuildLogo(cl
, obj
)) != NULL
)
623 DoMethod(data
->logoGroup
, MUIM_Group_AddHead
, data
->logo
);
625 set(data
->appInfoText
, MUIA_Text_Contents
, BuildAppInfo(cl
, obj
));
626 set(data
->creditsText
, MUIA_Text_Contents
, ParseCredits(cl
, obj
));
628 snprintf(data
->title
, sizeof(data
->title
), "About %s", (char *)XGET(_app(obj
), MUIA_Application_Title
));
629 set(obj
, MUIA_Window_Title
, data
->title
);
635 IPTR
Aboutbox__MUIM_Window_Cleanup(struct IClass
*cl
, Object
*obj
, Msg msg
)
637 struct Data
*data
= INST_DATA(cl
, obj
);
639 if(data
->logo
!= NULL
)
641 DoMethod(data
->logoGroup
, OM_REMMEMBER
, data
->logo
);
642 MUI_DisposeObject(data
->logo
);
646 clearExpandStr(&data
->appInfo
);
647 clearExpandStr(&data
->parsedCredits
);
649 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);