In Zune classes include <proto/alib.h> for BOOPSI related functions
[AROS.git] / workbench / classes / zune / aboutbox / Aboutbox.c
blobaad71650a4a78998aee66f52d08d9fd0a570883f
1 /*
2 Copyright © 2011, Thore Böckelmann. All rights reserved.
3 Copyright © 2012, The AROS Development Team. All rights reserved.
4 $Id$
5 */
8 #include <proto/exec.h>
9 #include <proto/dos.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"
23 #include <strings.h>
24 #include <stdio.h>
26 #ifndef ICONDRAWA_Transparency
27 #define ICONDRAWA_Transparency TAG_IGNORE
28 #endif
30 #ifndef MAX
31 #define MAX(a,b) ((a)>(b)?(a):(b))
32 #endif
34 #ifndef DtpicObject
35 #define DtpicObject MUIOBJMACRO_START(MUIC_Dtpic)
36 #endif
38 struct MUI_CustomClass *icon_mcc;
40 /* ------------------------------------------------------------------------- */
42 static BOOL FileExists(CONST_STRPTR filename)
44 if (filename == NULL)
46 return FALSE;
49 BOOL retval = FALSE;
51 BPTR lock = Lock(filename, ACCESS_READ);
52 if (lock)
54 struct FileInfoBlock *fib = AllocDosObject(DOS_FIB, NULL);
55 if (fib)
57 BOOL ex = Examine(lock, fib);
58 if (ex)
60 if (fib->fib_DirEntryType < 0) // File
62 retval = TRUE;
65 FreeDosObject(DOS_FIB, fib);
67 UnLock(lock);
69 return retval;
72 static void clearExpandStr(struct ExpandString *es)
74 if(es->string != NULL)
75 es->string[0] = '\0';
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)
85 char *newString;
86 ULONG newSize;
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);
95 FreeVec(es->string);
97 else
99 newString[0] = '\0';
102 es->string = newString;
103 es->size = newSize;
107 if(es->string != NULL)
109 strlcat(es->string, append, es->size);
113 static void freeExpandString(struct ExpandString *es)
115 if(es->string != NULL)
117 FreeVec(es->string);
118 es->string = NULL;
122 static char *BuildAppInfo(struct IClass *cl, Object *obj)
124 struct Data *data = INST_DATA(cl, obj);
125 char *info;
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)
144 info += 6;
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;
163 char c[2];
164 enum { ps_Text, ps_Placeholder } state;
166 state = ps_Text;
168 clearExpandStr(&data->parsedCredits);
169 appendExpandStr(&data->parsedCredits, "\n");
171 // set up a trailing NUL for single characters
172 c[1] = '\0';
174 while((c[0] = *credits++) != '\0')
176 switch(state)
178 case ps_Text:
180 switch(c[0])
182 case '%':
183 state = ps_Placeholder;
184 break;
186 case '\t':
187 appendExpandStr(&data->parsedCredits, " ");
188 break;
190 default:
191 appendExpandStr(&data->parsedCredits, c);
192 break;
195 break;
197 case ps_Placeholder:
199 switch(c[0])
201 case '%':
202 appendExpandStr(&data->parsedCredits, c);
203 break;
205 case 'a':
206 appendExpandStr(&data->parsedCredits, "Acknowledgements:");
207 break;
209 case 'd':
210 appendExpandStr(&data->parsedCredits, "Documentation:");
211 break;
213 case 'g':
214 appendExpandStr(&data->parsedCredits, "Graphics:");
215 break;
217 case 'i':
218 appendExpandStr(&data->parsedCredits, "Icons:");
219 break;
221 case 'I':
222 appendExpandStr(&data->parsedCredits, "Icon:");
223 break;
225 case 'l':
226 appendExpandStr(&data->parsedCredits, "Translations:");
227 break;
229 case 'L':
230 appendExpandStr(&data->parsedCredits, "Proofreading:");
231 break;
233 case 'm':
234 appendExpandStr(&data->parsedCredits, "Music:");
235 break;
237 case 'p':
238 appendExpandStr(&data->parsedCredits, "Programming:");
239 break;
241 case 'P':
242 appendExpandStr(&data->parsedCredits, "Additional programming:");
243 break;
245 case 's':
246 appendExpandStr(&data->parsedCredits, "Sound effects:");
247 break;
249 case 't':
250 appendExpandStr(&data->parsedCredits, "Thanks to:");
251 break;
253 case 'T':
254 appendExpandStr(&data->parsedCredits, "Special thanks to:");
255 break;
257 case 'W':
258 appendExpandStr(&data->parsedCredits, "Web support:");
259 break;
261 case '?':
262 appendExpandStr(&data->parsedCredits, "Disclaimer:");
263 break;
265 case '$':
266 appendExpandStr(&data->parsedCredits, "License:");
267 break;
269 default:
270 appendExpandStr(&data->parsedCredits, c);
271 break;
274 state = ps_Text;
276 break;
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));
305 #endif
306 #endif
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;
320 STRPTR file = NULL;
321 struct Screen *screen = NULL;
322 const struct TagItem *tstate = msg->ops_AttrList;
323 struct TagItem *tag;
325 while ((tag = NextTagItem(&tstate)) != NULL)
327 switch(tag->ti_Tag)
329 case MUIA_Icon_DiskObject:
330 icon = (struct DiskObject *)tag->ti_Data;
331 break;
333 case MUIA_Icon_File:
334 file = (STRPTR)tag->ti_Data;
335 break;
337 case MUIA_Icon_Screen:
338 screen = (struct Screen *)tag->ti_Data;
339 break;
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,
351 TAG_DONE)) == NULL)
352 goto error;
355 if((obj = (Object *)DoSuperNewTags(cl, obj, NULL,
356 MUIA_FillArea, TRUE,
357 TAG_MORE, msg->ops_AttrList)) != NULL)
359 struct Icon_Data *data = INST_DATA(cl, obj);
361 data->icon = icon;
363 else
365 FreeDiskObject(icon);
366 goto error;
369 return (IPTR)obj;
371 error:
372 return (IPTR)NULL;
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;
389 ULONG ret;
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,
396 TAG_DONE))
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;
410 return ret;
413 IPTR Icon__MUIM_Draw(struct IClass *cl, Object *obj, struct MUIP_Draw *msg)
415 struct Icon_Data *data = INST_DATA(cl, obj);
416 ULONG ret;
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,
426 TAG_DONE);
429 return ret;
432 /* ------------------------------------------------------------------------- */
434 IPTR Aboutbox__OM_NEW(struct IClass *cl, Object *obj, struct opSet *msg)
436 const struct TagItem *tstate = msg->ops_AttrList;
437 struct TagItem *tag;
439 Object *logoGroup;
440 Object *appInfoText;
441 Object *creditsText;
442 Object *okButton;
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,
452 #if 0
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,
460 #endif
461 MUIA_Window_UseRightBorderScroller, TRUE,
462 MUIA_Window_CloseGadget, FALSE,
463 MUIA_Window_SizeRight, TRUE,
464 WindowContents, VGroup,
465 Child, HGroup,
466 Child, logoGroup = VGroup,
467 Child, VSpace(0),
468 End,
469 Child, ScrollgroupObject,
470 MUIA_Weight, 100,
471 MUIA_Scrollgroup_FreeHoriz, FALSE,
472 MUIA_Scrollgroup_UseWinBorder, TRUE,
473 MUIA_Scrollgroup_Contents, VGroupV,
474 VirtualFrame,
475 Child, appInfoText = TextObject, End,
476 Child, RectangleObject, MUIA_Rectangle_HBar, TRUE, End,
477 Child, creditsText = TextObject, End,
478 End,
479 End,
480 End,
481 Child, HGroup,
482 Child, HSpace(0),
483 Child, okButton = SimpleButton("_Ok"),
484 Child, HSpace(0),
485 End,
486 End,
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)
498 switch(tag->ti_Tag)
500 case MUIA_Aboutbox_Credits:
501 data->credits = (CONST_STRPTR)tag->ti_Data;
502 break;
504 case MUIA_Aboutbox_Build:
505 data->build = (CONST_STRPTR)tag->ti_Data;
506 break;
508 case MUIA_Aboutbox_LogoFallbackMode:
509 data->fallbackMode = tag->ti_Data;
510 break;
512 case MUIA_Aboutbox_LogoFile:
513 data->logoFile = (CONST_STRPTR)tag->ti_Data;
514 break;
516 case MUIA_Aboutbox_LogoData:
517 data->logoData = (CONST_APTR)tag->ti_Data;
518 break;
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);
526 return (IPTR)obj;
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;
545 Object *logo = NULL;
547 while(fallbackMode != MUIV_Aboutbox_LogoFallbackMode_NoLogo && logo == NULL)
549 ULONG mode;
551 mode = (fallbackMode >> 24) & 0xff;
552 fallbackMode <<= 8;
554 switch(mode)
556 case 'D':
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)
569 char tempPath[256];
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),
579 TAG_DONE);
581 break;
583 case 'E':
585 if(data->logoFile != NULL && FileExists(data->logoFile))
587 logo = DtpicObject,
588 MUIA_Dtpic_Name, data->logoFile,
589 End;
592 break;
594 case 'I':
596 if(data->logoData != NULL)
598 logo = RawimageObject,
599 MUIA_Rawimage_Data, data->logoData,
600 End;
603 break;
605 case '\0':
606 fallbackMode = MUIV_Aboutbox_LogoFallbackMode_NoLogo;
607 break;
611 return logo;
614 IPTR Aboutbox__MUIM_Window_Setup(struct IClass *cl, Object *obj, Msg msg)
616 ULONG ret;
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);
632 return ret;
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);
643 data->logo = NULL;
646 clearExpandStr(&data->appInfo);
647 clearExpandStr(&data->parsedCredits);
649 return DoSuperMethodA(cl, obj, (Msg)msg);