2 Copyright © 2013-2016, The AROS Development Team. All rights reserved.
7 #include <aros/debug.h>
9 #define MUIMASTER_YES_INLINE_STDARG
11 #include <zune/customclasses.h>
12 #include <zune/prefseditor.h>
14 #include <proto/exec.h>
15 #include <proto/dos.h>
16 #include <proto/intuition.h>
17 #include <proto/muimaster.h>
19 #include <proto/alib.h>
21 #include <libraries/mui.h>
27 #include "appearanceeditor.h"
28 #include "themepreview.h"
30 /*** Instance Data **********************************************************/
32 struct AppearanceEditor_DATA
34 Object
*ae_ThemePreview
;
35 Object
*ae_ThemeEnable
;
36 Object
*ae_ThemeChoice
;
37 Object
*ae_OptionZune
;
39 Object
*ae_OptionWand
;
42 Object
*ae_CompEnable
;
49 struct Hook ae_PreviewHook
;
52 static STRPTR THEMES_DEFAULT
;
53 static STRPTR THEMES_AMIGAOS
= "AmigaOS3.x";
54 static CONST_STRPTR THEMES_BASE
= "THEMES:";
55 static CONST_STRPTR THEMES_ENVPATH
= "SYS/theme.var";
56 static CONST_STRPTR COMPOSITE_ENVPATH
= "SYS/compositor.prefs";
57 static CONST_STRPTR THEMES_DEFPATH
= "SYS:Prefs/Presets/theme.default";
58 static CONST_STRPTR THEMES_OPTZUNEPATH
= "Zune/usethemeprefs";
60 #define COMPOSITE_PEFSTEMPLATE "ABOVE/S,BELOW/S,LEFT/S,RIGHT/S,ALPHA/S"
72 /*** Macros *****************************************************************/
73 #define SETUP_INST_DATA struct AppearanceEditor_DATA *data = INST_DATA(CLASS, self)
75 static IPTR
AppearanceEditor__ListToArray(struct List
*ThemeList
)
77 int ThemeCount
= 0, i
= 0;
78 IPTR
*ThemeArray
= NULL
;
79 struct Node
*ThemeEntry
, *TmpNode
;
81 D(bug("[AppearanceEditor] %s()\n", __PRETTY_FUNCTION__
));
83 ForeachNode(ThemeList
, ThemeEntry
)
88 ThemeArray
= AllocVec(sizeof(IPTR
) * (ThemeCount
+ 1), MEMF_CLEAR
);
89 D(bug("[AppearanceEditor] %s: Array for %d Entries @ 0x%p\n", __PRETTY_FUNCTION__
, ThemeCount
, ThemeArray
));
91 ForeachNodeSafe(ThemeList
, ThemeEntry
, TmpNode
)
94 D(bug("[AppearanceEditor] %s: %02d: %s\n", __PRETTY_FUNCTION__
, i
, ThemeEntry
->ln_Name
));
95 ThemeArray
[i
++] = (IPTR
)ThemeEntry
->ln_Name
;
99 return (IPTR
)ThemeArray
;
102 /* N.B. This hook doesn't currently produce any preview of the selected theme.
103 * It just updates gadgets to match other gadgets and marks prefs as changed */
104 AROS_UFH3(static void, AppearanceEditor__PreviewHookFunc
,
105 AROS_UFHA(struct Hook
*, h
, A0
),
106 AROS_UFHA(Object
*, self
, A2
),
107 AROS_UFHA(APTR
, msg
, A1
))
110 struct AppearanceEditor_DATA
*data
= h
->h_Data
;
111 BOOL themeEnable
, compEnable
;
112 D(bug("[AppearanceEditor] %s()\n", __PRETTY_FUNCTION__
));
114 themeEnable
= (BOOL
)XGET(data
->ae_ThemeEnable
, MUIA_Selected
);
115 SET(data
->ae_ThemeChoice
, MUIA_Disabled
, !(themeEnable
));
116 SET(data
->ae_OptionZune
, MUIA_Disabled
, !(themeEnable
));
118 SET(data
->ae_OptionWand
, MUIA_Disabled
, !(themeEnable
));
121 compEnable
= (BOOL
)XGET(data
->ae_CompEnable
, MUIA_Selected
);
122 SET(data
->ae_CompBelow
, MUIA_Disabled
, !(compEnable
));
123 SET(data
->ae_CompLeft
, MUIA_Disabled
, !(compEnable
));
124 SET(data
->ae_CompRight
, MUIA_Disabled
, !(compEnable
));
125 SET(data
->ae_CompAlpha
, MUIA_Disabled
, !(compEnable
));
127 SET(self
, MUIA_PrefsEditor_Changed
, TRUE
);
132 static Object
*MakeCheckmark(BOOL selected
)
134 Object
*obj
= MUI_MakeObject(MUIO_Checkmark
, (IPTR
)NULL
);
138 SET(obj
, MUIA_CycleChain
, 1);
139 SET(obj
, MUIA_Selected
, selected
);
144 #define kExallBufSize (4096)
146 /*** Methods ****************************************************************/
147 Object
*AppearanceEditor__OM_NEW(Class
*CLASS
, Object
*self
, struct opSet
*message
)
149 UBYTE
*ExAllBuffer
= NULL
;
153 Object
*_ThemePreviewObj
;
155 Object
*_ThemeEnable
;
156 Object
*_ThemeSelectionObj
;
158 Object
*_ThemeWandPrefsObj
;
160 Object
*_ThemeZunePrefsObj
;
167 struct List _ThemesAvailable
;
168 struct Node
*_ThemeEntry
;
169 IPTR _ThemeArray
= (IPTR
)NULL
;
171 BPTR _ThemeLock
= BNULL
;
173 D(bug("[AppearanceEditor] %s()\n", __PRETTY_FUNCTION__
));
175 NewList(&_ThemesAvailable
);
177 // Find Available Themes
178 if ((ExAllBuffer
= AllocVec(kExallBufSize
, MEMF_CLEAR
|MEMF_PUBLIC
)) != NULL
)
180 if (GetVar(THEMES_DEFPATH
, ExAllBuffer
, kExallBufSize
, GVF_GLOBAL_ONLY
) == -1)
181 THEMES_DEFAULT
= THEMES_AMIGAOS
;
184 THEMES_DEFAULT
= AllocVec(strlen(ExAllBuffer
) + 1, MEMF_CLEAR
);
185 CopyMem(ExAllBuffer
, (APTR
)THEMES_DEFAULT
, strlen(ExAllBuffer
));
188 if ((_ThemeLock
= Lock(THEMES_BASE
, SHARED_LOCK
)) != BNULL
)
190 struct ExAllControl
*eac
;
191 if ((eac
= AllocDosObject(DOS_EXALLCONTROL
,NULL
)) != NULL
)
193 struct ExAllData
*ead
= (struct ExAllData
*)ExAllBuffer
;
194 eac
->eac_LastKey
= 0;
196 ExAllMore
= ExAll(_ThemeLock
, ead
, kExallBufSize
, ED_COMMENT
, eac
);
197 if ((!ExAllMore
) && (IoErr() != ERROR_NO_MORE_ENTRIES
)) {
200 if (eac
->eac_Entries
== 0) {
203 ead
= (struct ExAllData
*)ExAllBuffer
;
205 if (ead
->ed_Type
== ST_USERDIR
)
207 _ThemeEntry
= AllocVec(sizeof(struct Node
), MEMF_CLEAR
);
208 _ThemeEntry
->ln_Name
= StrDup(ead
->ed_Name
);
209 AddTail(&_ThemesAvailable
, _ThemeEntry
);
214 FreeDosObject(DOS_EXALLCONTROL
, eac
);
216 FreeVec(ExAllBuffer
);
221 //TODO: Display a warning about missing themes: assign
226 // Catastrophic failure - not enough memory to allocate exall buffer =S
227 return (Object
*)NULL
;
230 _ThemeArray
= AppearanceEditor__ListToArray(&_ThemesAvailable
);
232 self
= (Object
*) DoSuperNewTags
235 MUIA_PrefsEditor_Name
, (IPTR
)_(MSG_WINTITLE
),
236 MUIA_PrefsEditor_Path
, (IPTR
) THEMES_ENVPATH
,
237 MUIA_PrefsEditor_IconTool
, (IPTR
) "SYS:Prefs/Theme",
238 MUIA_PrefsEditor_CanTest
, FALSE
,
239 MUIA_PrefsEditor_CanUse
, FALSE
,
243 Child
, (IPTR
)(_ThemePreviewObj
= ThemePreviewObject
,
249 GroupFrameT(_(MSG_SEC_THEMING
)),
251 Child
, (IPTR
)(_ThemeEnable
= MakeCheckmark(TRUE
)),
252 Child
, (IPTR
)Label1(_(MSG_ENABLETHEMES
)),
253 Child
, (IPTR
)HVSpace
,
256 Child
, (IPTR
)Label1(_(MSG_SELECTEDTHEME
)),
257 Child
, (IPTR
)(_ThemeSelectionObj
= CycleObject
,
259 MUIA_Cycle_Entries
, (IPTR
)_ThemeArray
,
263 Child
, (IPTR
)(_ThemeZunePrefsObj
= MakeCheckmark(TRUE
)),
264 Child
, (IPTR
)Label1(_(MSG_ENABLEZUNEPREFS
)),
265 Child
, (IPTR
)HVSpace
,
268 Child
, (IPTR
)Label1(_(MSG_ENABLEWANDPREFS
)),
270 Child
, (IPTR
)(_ThemeWandPrefsObj
= MakeCheckmark(TRUE
)),
271 Child
, (IPTR
)HVSpace
,
274 Child
, (IPTR
)HVSpace
,
278 GroupFrameT(_(MSG_SEC_COMPOSITING
)),
279 MUIA_Group_SameWidth
, FALSE
,
281 Child
, (IPTR
)(_CompEnable
= MakeCheckmark(TRUE
)),
282 Child
, (IPTR
)Label1(__(MSG_ENABLE_SCREEN_COMPOSITION
)),
283 Child
, (IPTR
)HVSpace
,
286 Child
, (IPTR
)(_CompBelow
= MakeCheckmark(FALSE
)),
287 Child
, (IPTR
)Label1(__(MSG_COMPOSITE_BELOW
)),
288 Child
, (IPTR
)HVSpace
,
291 Child
, (IPTR
)(_CompLeft
= MakeCheckmark(FALSE
)),
292 Child
, (IPTR
)Label1(__(MSG_COMPOSITE_LEFT
)),
293 Child
, (IPTR
)HVSpace
,
296 Child
, (IPTR
)(_CompRight
= MakeCheckmark(FALSE
)),
297 Child
, (IPTR
)Label1(__(MSG_COMPOSITE_RIGHT
)),
298 Child
, (IPTR
)HVSpace
,
301 Child
, (IPTR
)(_CompAlpha
= MakeCheckmark(FALSE
)),
302 Child
, (IPTR
)Label1(__(MSG_ENABLE_COMPOSITE_WITH_ALPHA
)),
303 Child
, (IPTR
)HVSpace
,
318 data
->ae_ThemePreview
= _ThemePreviewObj
;
320 data
->ae_ThemeEnable
= _ThemeEnable
;
321 data
->ae_ThemeChoice
= _ThemeSelectionObj
;
322 data
->ae_OptionZune
= _ThemeZunePrefsObj
;
324 data
->ae_OptionWand
= _ThemeWandPrefsObj
;
327 data
->ae_CompEnable
= _CompEnable
;
328 data
->ae_CompBelow
= _CompBelow
;
329 data
->ae_CompLeft
= _CompLeft
;
330 data
->ae_CompRight
= _CompRight
;
331 data
->ae_CompAlpha
= _CompAlpha
;
333 data
->ae_ThemeArray
= (IPTR
*)_ThemeArray
;
335 data
->ae_PreviewHook
.h_Entry
= (HOOKFUNC
)AppearanceEditor__PreviewHookFunc
;
336 data
->ae_PreviewHook
.h_Data
= data
;
340 data
->ae_ThemeEnable
, MUIM_Notify
, MUIA_Selected
, MUIV_EveryTime
,
341 (IPTR
) self
, 3, MUIM_CallHook
, (IPTR
)&data
->ae_PreviewHook
, (IPTR
)NULL
346 data
->ae_ThemeChoice
, MUIM_Notify
, MUIA_Cycle_Active
, MUIV_EveryTime
,
347 (IPTR
) self
, 3, MUIM_CallHook
, (IPTR
)&data
->ae_PreviewHook
, (IPTR
)NULL
352 data
->ae_OptionZune
, MUIM_Notify
, MUIA_Selected
, MUIV_EveryTime
,
353 (IPTR
) self
, 3, MUIM_CallHook
, (IPTR
)&data
->ae_PreviewHook
, (IPTR
)NULL
358 data
->ae_OptionWand
, MUIM_Notify
, MUIA_Selected
, MUIV_EveryTime
,
359 (IPTR
) self
, 3, MUIM_CallHook
, (IPTR
)&data
->ae_PreviewHook
, (IPTR
)NULL
365 data
->ae_CompEnable
, MUIM_Notify
, MUIA_Selected
, MUIV_EveryTime
,
366 (IPTR
) self
, 3, MUIM_CallHook
, (IPTR
)&data
->ae_PreviewHook
, (IPTR
)NULL
371 data
->ae_CompBelow
, MUIM_Notify
, MUIA_Selected
, MUIV_EveryTime
,
372 (IPTR
) self
, 3, MUIM_CallHook
, (IPTR
)&data
->ae_PreviewHook
, (IPTR
)NULL
377 data
->ae_CompLeft
, MUIM_Notify
, MUIA_Selected
, MUIV_EveryTime
,
378 (IPTR
) self
, 3, MUIM_CallHook
, (IPTR
)&data
->ae_PreviewHook
, (IPTR
)NULL
383 data
->ae_CompRight
, MUIM_Notify
, MUIA_Selected
, MUIV_EveryTime
,
384 (IPTR
) self
, 3, MUIM_CallHook
, (IPTR
)&data
->ae_PreviewHook
, (IPTR
)NULL
389 data
->ae_CompAlpha
, MUIM_Notify
, MUIA_Selected
, MUIV_EveryTime
,
390 (IPTR
) self
, 3, MUIM_CallHook
, (IPTR
)&data
->ae_PreviewHook
, (IPTR
)NULL
397 IPTR
AppearanceEditor__OM_DISPOSE(Class
*CLASS
, Object
*self
, struct opSet
*message
)
402 D(bug("[AppearanceEditor] %s()\n", __PRETTY_FUNCTION__
));
404 while (data
->ae_ThemeArray
[index
] != (IPTR
)NULL
)
406 D(bug("[AppearanceEditor] %s: Freeing %02d: %s\n", __PRETTY_FUNCTION__
, index
, data
->ae_ThemeArray
[index
]));
407 FreeVec((APTR
)data
->ae_ThemeArray
[index
]);
410 FreeVec((APTR
)data
->ae_ThemeArray
);
412 if (THEMES_DEFAULT
!= THEMES_AMIGAOS
)
413 FreeVec(THEMES_DEFAULT
);
415 return DoSuperMethodA(CLASS
, self
, message
);
418 IPTR AppearanceEditor__MUIM_PrefsEditor_Import
420 Class
*CLASS
, Object
*self
,
421 struct MUIP_PrefsEditor_Import
*message
428 D(bug("[AppearanceEditor] %s()\n", __PRETTY_FUNCTION__
));
430 if ((fh
= Open(message
->filename
, MODE_OLDFILE
)) != BNULL
)
432 NNSET(data
->ae_ThemeEnable
, MUIA_Selected
, TRUE
);
433 SET(data
->ae_ThemeChoice
, MUIA_Disabled
, FALSE
);
434 SET(data
->ae_OptionZune
, MUIA_Disabled
, FALSE
);
436 SET(data
->ae_OptionWand
, MUIA_Disabled
, FALSE
);
438 success
= DoMethod(self
, MUIM_PrefsEditor_ImportFH
, (IPTR
) fh
);
443 NNSET(data
->ae_ThemeEnable
, MUIA_Selected
, FALSE
);
444 SET(data
->ae_ThemeChoice
, MUIA_Disabled
, TRUE
);
445 SET(data
->ae_OptionZune
, MUIA_Disabled
, TRUE
);
447 SET(data
->ae_OptionWand
, MUIA_Disabled
, TRUE
);
449 success
= DoMethod(self
, MUIM_PrefsEditor_ImportFH
, NULL
);
455 IPTR
AppearanceEditor__MUIM_PrefsEditor_ImportFH (
456 Class
*CLASS
, Object
*self
,
457 struct MUIP_PrefsEditor_ImportFH
*message
461 BOOL success
= TRUE
, optzune
= TRUE
;
462 TEXT importBuffer
[1024];
465 D(bug("[AppearanceEditor] %s(FH@ 0x%p)\n", __PRETTY_FUNCTION__
, message
->fh
));
469 if (FGets(message
->fh
, importBuffer
, 1024))
471 char *tmpThemeFile
= FilePart(importBuffer
);
473 D(bug("[AppearanceEditor] %s: Prefs Theme = '%s'\n", __PRETTY_FUNCTION__
, tmpThemeFile
));
475 while (data
->ae_ThemeArray
[index
] != (IPTR
)NULL
)
477 if (strncmp((char *)data
->ae_ThemeArray
[index
], tmpThemeFile
, strlen((char *)data
->ae_ThemeArray
[index
])) == 0)
479 NNSET(data
->ae_ThemeChoice
, MUIA_Cycle_Active
, index
);
485 if (GetVar(THEMES_OPTZUNEPATH
, importBuffer
, 1, GVF_GLOBAL_ONLY
) == -1)
488 NNSET(data
->ae_OptionZune
, MUIA_Selected
, optzune
);
491 if (GetVar(COMPOSITE_ENVPATH
, importBuffer
, 1024, GVF_GLOBAL_ONLY
) != -1)
493 struct RDArgs
*rdargs
;
494 IPTR CompArgs
[NOOFARGS
] = { 0 };
496 if ((rdargs
= AllocDosObjectTags(DOS_RDARGS
, TAG_END
)) != NULL
)
498 rdargs
->RDA_Source
.CS_Buffer
= importBuffer
;
499 rdargs
->RDA_Source
.CS_Length
= strlen(rdargs
->RDA_Source
.CS_Buffer
);
500 rdargs
->RDA_DAList
= (IPTR
)NULL
;
501 rdargs
->RDA_Buffer
= NULL
;
502 rdargs
->RDA_BufSiz
= 0;
503 rdargs
->RDA_ExtHelp
= NULL
;
504 rdargs
->RDA_Flags
= 0;
506 if (ReadArgs(COMPOSITE_PEFSTEMPLATE
, CompArgs
, rdargs
) != NULL
)
508 NNSET(data
->ae_CompEnable
, MUIA_Selected
, (BOOL
)CompArgs
[ARG_ABOVE
]);
509 NNSET(data
->ae_CompBelow
, MUIA_Selected
, (BOOL
)CompArgs
[ARG_BELOW
]);
510 NNSET(data
->ae_CompLeft
, MUIA_Selected
, (BOOL
)CompArgs
[ARG_LEFT
]);
511 NNSET(data
->ae_CompRight
, MUIA_Selected
, (BOOL
)CompArgs
[ARG_RIGHT
]);
512 NNSET(data
->ae_CompAlpha
, MUIA_Selected
, (BOOL
)CompArgs
[ARG_ALPHA
]);
515 FreeDosObject(DOS_RDARGS
, rdargs
);
521 IPTR AppearanceEditor__MUIM_PrefsEditor_Export
523 Class
*CLASS
, Object
*self
,
524 struct MUIP_PrefsEditor_Export
*message
530 D(bug("[AppearanceEditor] %s()\n", __PRETTY_FUNCTION__
));
532 if (XGET(data
->ae_ThemeEnable
, MUIA_Selected
))
534 success
= DoSuperMethodA(CLASS
, self
, message
);
538 DeleteVar(THEMES_ENVPATH
, GVF_GLOBAL_ONLY
| GVF_SAVE_VAR
);
544 IPTR AppearanceEditor__MUIM_PrefsEditor_ExportFH
546 Class
*CLASS
, Object
*self
,
547 struct MUIP_PrefsEditor_ExportFH
*message
551 BOOL success
= TRUE
, backup
;
555 D(bug("[AppearanceEditor] %s(FH@ 0x%p)\n", __PRETTY_FUNCTION__
, message
->fh
));
557 if ((exportBuffer
= AllocVec(1024, MEMF_CLEAR
)) != NULL
)
559 /* Check if the generic prefs editor class is just making a backup */
560 NameFromFH(message
->fh
, exportBuffer
, 1024);
561 backup
= strstr(exportBuffer
, "theme.var") == NULL
;
565 GET(data
->ae_ThemeChoice
, MUIA_Cycle_Active
, &active
);
566 D(bug("[AppearanceEditor] %s: Selected Theme = [%02d] '%s'\n", __PRETTY_FUNCTION__
, active
, data
->ae_ThemeArray
[active
]));
568 sprintf(exportBuffer
, "%s%s", THEMES_BASE
, (char *)data
->ae_ThemeArray
[active
]);
570 if (FPuts(message
->fh
, exportBuffer
))
575 if (XGET(data
->ae_OptionZune
, MUIA_Selected
))
577 sprintf(exportBuffer
, "True");
578 SetVar(THEMES_OPTZUNEPATH
, exportBuffer
, 4,
579 GVF_GLOBAL_ONLY
| GVF_SAVE_VAR
);
583 DeleteVar(THEMES_OPTZUNEPATH
,
584 GVF_GLOBAL_ONLY
| GVF_SAVE_VAR
);
587 // TODO: Signal Decoration to reload the theme
589 if (XGET(data
->ae_CompEnable
, MUIA_Selected
) && !backup
)
593 sprintf(exportBuffer
, "ABOVE");
594 ebPos
= strlen(exportBuffer
);
595 if (XGET(data
->ae_CompBelow
, MUIA_Selected
))
597 sprintf(exportBuffer
+ ebPos
, " BELOW");
598 ebPos
= strlen(exportBuffer
);
600 if (XGET(data
->ae_CompLeft
, MUIA_Selected
))
602 sprintf(exportBuffer
+ ebPos
, " LEFT");
603 ebPos
= strlen(exportBuffer
);
605 if (XGET(data
->ae_CompRight
, MUIA_Selected
))
607 sprintf(exportBuffer
+ ebPos
, " RIGHT");
608 ebPos
= strlen(exportBuffer
);
610 if (XGET(data
->ae_CompAlpha
, MUIA_Selected
))
612 sprintf(exportBuffer
+ ebPos
, " ALPHA");
613 ebPos
= strlen(exportBuffer
);
615 SetVar(COMPOSITE_ENVPATH
, exportBuffer
, ebPos
,
616 GVF_GLOBAL_ONLY
| GVF_SAVE_VAR
);
620 DeleteVar(COMPOSITE_ENVPATH
, GVF_GLOBAL_ONLY
| GVF_SAVE_VAR
);
623 FreeVec(exportBuffer
);
627 IPTR AppearanceEditor__MUIM_PrefsEditor_SetDefaults
629 Class
*CLASS
, Object
*self
, Msg message
635 D(bug("[AppearanceEditor] %s()\n", __PRETTY_FUNCTION__
));
638 while (data
->ae_ThemeArray
[index
] != (IPTR
)NULL
)
640 if (!strcmp((char *)data
->ae_ThemeArray
[index
], THEMES_DEFAULT
))
642 SET(data
->ae_ThemeChoice
, MUIA_Cycle_Active
, index
);
647 SET(data
->ae_OptionZune
, MUIA_Selected
, TRUE
);
649 SET(data
->ae_OptionWand
, MUIA_Selected
, TRUE
);
652 // Compositor options
653 SET(data
->ae_CompEnable
, MUIA_Selected
, TRUE
);
654 SET(data
->ae_CompBelow
, MUIA_Selected
, FALSE
);
655 SET(data
->ae_CompLeft
, MUIA_Selected
, FALSE
);
656 SET(data
->ae_CompRight
, MUIA_Selected
, FALSE
);
657 SET(data
->ae_CompAlpha
, MUIA_Selected
, TRUE
);
662 /*** Setup ******************************************************************/
665 AppearanceEditor
, NULL
, MUIC_PrefsEditor
, NULL
,
666 OM_NEW
, struct opSet
*,
667 OM_DISPOSE
, struct opSet
*,
668 MUIM_PrefsEditor_Import
, struct MUIP_PrefsEditor_Import
*,
669 MUIM_PrefsEditor_ImportFH
, struct MUIP_PrefsEditor_ImportFH
*,
670 MUIM_PrefsEditor_Export
, struct MUIP_PrefsEditor_Export
*,
671 MUIM_PrefsEditor_ExportFH
, struct MUIP_PrefsEditor_ExportFH
*,
672 MUIM_PrefsEditor_SetDefaults
, Msg