Example #1
0
        public static void ApplyTheme(Application app, ThemeDescription theme, ApplicationMode mode)
        {
            var allLoaded   = true;
            var loadedXamls = new List <ResourceDictionary>();
            var xamlFiles   = Directory.GetFiles(theme.DirectoryPath, "*.xaml", SearchOption.AllDirectories);

            foreach (var xamlFile in xamlFiles)
            {
                try
                {
                    var xaml = Xaml.FromFile(xamlFile);
                    if (xaml is ResourceDictionary xamlDir)
                    {
                        xamlDir.Source = new Uri(xamlFile, UriKind.Absolute);
                        loadedXamls.Add(xamlDir as ResourceDictionary);
                    }
                    else
                    {
                        logger.Error($"Skipping theme file {xamlFile}, it's not resource dictionary.");
                    }
                }
                catch (Exception e) when(!PlayniteEnvironment.ThrowAllErrors)
                {
                    logger.Error(e, $"Failed to load xaml {xamlFiles}");
                    allLoaded = false;
                    break;
                }
            }

            if (allLoaded)
            {
                loadedXamls.ForEach(a => app.Resources.MergedDictionaries.Add(a));
            }
        }
Example #2
0
        public static bool ApplyTheme(Application app, ThemeDescription theme, ApplicationMode mode)
        {
            if ((new System.Version(theme.ThemeApiVersion).Major != ThemeApiVersion.Major))
            {
                logger.Error($"Failed to apply {theme.Name} theme, unsupported API version {theme.ThemeApiVersion}.");
                return(false);
            }

            var allLoaded       = true;
            var loadedXamls     = new List <ResourceDictionary>();
            var acceptableXamls = new List <string>();
            var defaultRoot     = $"Themes/{mode.GetDescription()}/{DefaultTheme.DirectoryName}/";

            foreach (var dict in app.Resources.MergedDictionaries)
            {
                if (dict.Source.OriginalString.StartsWith("Themes") && dict.Source.OriginalString.EndsWith("xaml"))
                {
                    acceptableXamls.Add(dict.Source.OriginalString.Replace(defaultRoot, "").Replace('/', '\\'));
                }
            }

            foreach (var accXaml in acceptableXamls)
            {
                var xamlPath = Path.Combine(theme.DirectoryPath, accXaml);
                if (!File.Exists(xamlPath))
                {
                    continue;
                }

                try
                {
                    var xaml = Xaml.FromFile(xamlPath);
                    if (xaml is ResourceDictionary xamlDir)
                    {
                        xamlDir.Source = new Uri(xamlPath, UriKind.Absolute);
                        loadedXamls.Add(xamlDir as ResourceDictionary);
                    }
                    else
                    {
                        logger.Error($"Skipping theme file {xamlPath}, it's not resource dictionary.");
                    }
                }
                catch (Exception e) when(!PlayniteEnvironment.ThrowAllErrors)
                {
                    logger.Error(e, $"Failed to load xaml {xamlPath}");
                    allLoaded = false;
                    break;
                }
            }

            if (allLoaded)
            {
                loadedXamls.ForEach(a => app.Resources.MergedDictionaries.Add(a));
                return(true);
            }

            return(false);
        }
Example #3
0
        public static void SetLanguage(string language)
        {
            var dictionaries = Application.Current.Resources.MergedDictionaries;

            if (CurrentLanguage != SourceLanguageId)
            {
                var currentLang = dictionaries.FirstOrDefault(a => a["LanguageName"] != null && a.Source == null);
                if (currentLang != null)
                {
                    dictionaries.Remove(currentLang);
                }
            }

            var langFile = Path.Combine(PlaynitePaths.LocalizationsPath, language + ".xaml");

            if (File.Exists(langFile) && language != SourceLanguageId)
            {
                ResourceDictionary res = null;
                try
                {
                    res        = Xaml.FromFile <ResourceDictionary>(langFile);
                    res.Source = new Uri(langFile, UriKind.Absolute);
                    // Unstranslated strings are imported as empty entries by Crowdin.
                    // We need to remove them to make sure that origina English text will be displayed instead.
                    foreach (var key in res.Keys)
                    {
                        if (res[key] is string locString && locString.IsNullOrEmpty())
                        {
                            res.Remove(key);
                        }
                    }
                }
                catch (Exception e) when(!PlayniteEnvironment.ThrowAllErrors)
                {
                    logger.Error(e, $"Failed to parse localization file {langFile}");
                    return;
                }

                dictionaries.Add(res);

                ApplicationLanguageCultureInfo = new CultureInfo(language.Replace("_", "-"), false);
            }
            else
            {
                ApplicationLanguageCultureInfo = new CultureInfo("en-US", false); // english is the default language
            }

            CurrentLanguage = language;
        }
Example #4
0
        /// <summary>
        /// Set in application ressources the common ressources.
        /// </summary>
        /// <param name="pluginFolder"></param>
        public static void Load(string pluginFolder)
        {
            List <string> ListCommonFiles = new List <string>
            {
                Path.Combine(pluginFolder, "Resources\\Common.xaml"),
                Path.Combine(pluginFolder, "Resources\\LiveChartsCommon\\Common.xaml")
            };

            foreach (string CommonFile in ListCommonFiles)
            {
                if (File.Exists(CommonFile))
                {
#if DEBUG
                    logger.Debug($"PluginCommon - Load {CommonFile}");
#endif

                    ResourceDictionary res = null;
                    try
                    {
                        res        = Xaml.FromFile <ResourceDictionary>(CommonFile);
                        res.Source = new Uri(CommonFile, UriKind.Absolute);

                        foreach (var key in res.Keys)
                        {
                            if (res[key] is string locString && locString.IsNullOrEmpty())
                            {
                                res.Remove(key);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        LogError(ex, "PluginCommon", $"Failed to parse file {CommonFile}");
                        return;
                    }

#if DEBUG
                    logger.Debug($"PluginCommon - res: {JsonConvert.SerializeObject(res)}");
#endif
                    Application.Current.Resources.MergedDictionaries.Add(res);
                }
                else
                {
                    logger.Warn($"PluginCommon - File {CommonFile} not found.");
                    return;
                }
            }
        }
Example #5
0
        public static List <PlayniteLanguage> GetLanguagesFromFolder(string path)
        {
            var langs = new List <PlayniteLanguage>()
            {
                new PlayniteLanguage()
                {
                    Id           = SourceLanguageId,
                    LocaleString = "English"
                }
            };

            if (!Directory.Exists(path))
            {
                return(langs);
            }

            foreach (var file in Directory.GetFiles(path, "*.xaml"))
            {
                if (!Regex.IsMatch(file, "[a-zA-Z]+_[a-zA-Z]+"))
                {
                    continue;
                }

                var langPath           = Path.Combine(path, file);
                ResourceDictionary res = null;
                try
                {
                    res = Xaml.FromFile <ResourceDictionary>(langPath);
                }
                catch (Exception e) when(!PlayniteEnvironment.ThrowAllErrors)
                {
                    logger.Error(e, $"Failed to parse localization file {file}");
                    continue;
                }

                langs.Add(new PlayniteLanguage()
                {
                    Id           = Path.GetFileNameWithoutExtension(langPath),
                    LocaleString = res["LanguageName"].ToString()
                });
            }

            return(langs.OrderBy(a => a.LocaleString).ToList());
        }
Example #6
0
        public static void ApplyFullscreenButtonPrompts(Application app, FullscreenButtonPrompts prompts)
        {
            if (prompts == FullscreenSettings.DefaultButtonPrompts)
            {
                var defaultXaml = $"{FullscreenSettings.DefaultButtonPrompts.ToString()}.xaml";
                foreach (var dir in PlayniteApplication.CurrentNative.Resources.MergedDictionaries.ToList())
                {
                    if (dir.Source == null)
                    {
                        continue;
                    }

                    if (dir.Source.OriginalString.Contains("ButtonPrompts") &&
                        !dir.Source.OriginalString.EndsWith(defaultXaml))
                    {
                        PlayniteApplication.CurrentNative.Resources.MergedDictionaries.Remove(dir);
                    }
                }
            }
            else
            {
                var promptsPath = Path.Combine(ThemeManager.DefaultTheme.DirectoryPath, "Images", "ButtonPrompts");
                foreach (var dir in Directory.GetDirectories(promptsPath))
                {
                    var dirInfo    = new DirectoryInfo(dir);
                    var promptXaml = Path.Combine(dir, $"{dirInfo.Name}.xaml");
                    if (File.Exists(promptXaml) && dirInfo.Name == prompts.ToString())
                    {
                        var xaml = Xaml.FromFile(promptXaml);
                        if (xaml is ResourceDictionary xamlDir)
                        {
                            xamlDir.Source = new Uri(promptXaml, UriKind.Absolute);
                            PlayniteApplication.CurrentNative.Resources.MergedDictionaries.Add(xamlDir);
                        }
                    }
                }
            }
        }
Example #7
0
        public TestResourceProvider()
        {
            var engSource = Path.Combine(PlaynitePaths.LocalizationsPath, PlaynitePaths.EngLocSourceFileName);

            engStringResource = Xaml.FromFile <ResourceDictionary>(engSource);
        }
Example #8
0
        public static AddonLoadError ApplyTheme(Application app, ThemeManifest theme, ApplicationMode mode)
        {
            if (theme.Id.IsNullOrEmpty())
            {
                logger.Error($"Theme {theme.Name}, doesn't have ID.");
                return(AddonLoadError.Uknown);
            }

            var apiVesion = mode == ApplicationMode.Desktop ? DesktopApiVersion : FullscreenApiVersion;

            if (!theme.ThemeApiVersion.IsNullOrEmpty())
            {
                var themeVersion = new Version(theme.ThemeApiVersion);
                if (themeVersion.Major != apiVesion.Major || themeVersion > apiVesion)
                {
                    logger.Error($"Failed to apply {theme.Name} theme, unsupported API version {theme.ThemeApiVersion}.");
                    return(AddonLoadError.SDKVersion);
                }
            }

            var acceptableXamls = new List <string>();
            var defaultRoot     = $"Themes/{mode.GetDescription()}/{DefaultTheme.DirectoryName}/";

            foreach (var dict in app.Resources.MergedDictionaries)
            {
                if (dict.Source.OriginalString.StartsWith(defaultRoot))
                {
                    acceptableXamls.Add(dict.Source.OriginalString.Replace(defaultRoot, "").Replace('/', '\\'));
                }
            }

            var allLoaded = true;

            foreach (var accXaml in acceptableXamls)
            {
                var xamlPath = Path.Combine(theme.DirectoryPath, accXaml);
                if (!File.Exists(xamlPath))
                {
                    continue;
                }

                try
                {
                    var xaml = Xaml.FromFile(xamlPath);
                }
                catch (Exception e) when(!PlayniteEnvironment.ThrowAllErrors)
                {
                    logger.Error(e, $"Failed to load xaml {xamlPath}");
                    allLoaded = false;
                    break;
                }
            }

            if (!allLoaded)
            {
                return(AddonLoadError.Uknown);
            }

            try
            {
                var cursorFile = ThemeFile.GetFilePath("cursor.cur");
                if (cursorFile.IsNullOrEmpty())
                {
                    cursorFile = ThemeFile.GetFilePath("cursor.ani");
                }

                if (!cursorFile.IsNullOrEmpty())
                {
                    Mouse.OverrideCursor = new Cursor(cursorFile, true);
                }
            }
            catch (Exception e) when(!PlayniteEnvironment.ThrowAllErrors)
            {
                logger.Error(e, "Failed to set custom mouse cursor.");
            }

            var themeRoot = $"Themes\\{mode.GetDescription()}\\{theme.DirectoryName}\\";

            // This is sad that we have to do this, but it fixes issues like #2328
            // We need to remove all loaded theme resources and reload them in specific order:
            //      default/1.xaml -> theme/1.xaml -> default/2.xaml -> theme/2.xaml etc.
            //
            // We can't just load custom theme files at the end or insert them in already loaded pool of resources
            // because styling with static references won't reload data from custom theme files.
            // That's why we also have to create new instances of default styles.
            foreach (var defaultRes in app.Resources.MergedDictionaries.ToList())
            {
                if (defaultRes.Source.OriginalString.StartsWith(defaultRoot))
                {
                    app.Resources.MergedDictionaries.Remove(defaultRes);
                }
            }

            foreach (var themeXamlFile in acceptableXamls)
            {
                var defaultPath = Path.Combine(PlaynitePaths.ThemesProgramPath, mode.GetDescription(), "Default", themeXamlFile);
                var defaultXaml = Xaml.FromFile(defaultPath);
                if (defaultXaml is ResourceDictionary xamlDir)
                {
                    xamlDir.Source = new Uri(defaultPath, UriKind.Absolute);
                    app.Resources.MergedDictionaries.Add(xamlDir);
                }

                var xamlPath = Path.Combine(theme.DirectoryPath, themeXamlFile);
                if (!File.Exists(xamlPath))
                {
                    continue;
                }

                var xaml = Xaml.FromFile(xamlPath);
                if (xaml is ResourceDictionary themeDir)
                {
                    themeDir.Source = new Uri(xamlPath, UriKind.Absolute);
                    app.Resources.MergedDictionaries.Add(themeDir);
                }
                else
                {
                    logger.Error($"Skipping theme file {xamlPath}, it's not resource dictionary.");
                }
            }

            return(AddonLoadError.None);
        }
        public static void SetPluginLanguage(string pluginFolder, string language, bool DefaultLoad = false)
        {
            // Load default for missing
            if (!DefaultLoad)
            {
                SetPluginLanguage(pluginFolder, "LocSource", true);
            }


            var dictionaries   = Application.Current.Resources.MergedDictionaries;
            var langFile       = Path.Combine(pluginFolder, "localization\\" + language + ".xaml");
            var langFileCommon = Path.Combine(pluginFolder, "localization\\Common\\" + language + ".xaml");


            // Load localization common
            if (File.Exists(langFileCommon))
            {
#if DEBUG
                logger.Debug($"PluginCommon - Parse plugin localization file {langFileCommon}.");
#endif

                ResourceDictionary res = null;
                try
                {
                    res        = Xaml.FromFile <ResourceDictionary>(langFileCommon);
                    res.Source = new Uri(langFileCommon, UriKind.Absolute);

                    foreach (var key in res.Keys)
                    {
                        if (res[key] is string locString && locString.IsNullOrEmpty())
                        {
                            res.Remove(key);
                        }
                    }
                }
                catch (Exception ex)
                {
                    logger.Error(ex, $"PluginCommon - Failed to parse localization file {langFileCommon}.");
                    return;
                }

                dictionaries.Add(res);
            }
            else
            {
                logger.Warn($"PluginCommon - File {langFileCommon} not found.");
            }


            // Load localization
            if (File.Exists(langFile))
            {
#if DEBUG
                logger.Debug($"PluginCommon - Parse plugin localization file {langFile}.");
#endif

                ResourceDictionary res = null;
                try
                {
                    res        = Xaml.FromFile <ResourceDictionary>(langFile);
                    res.Source = new Uri(langFile, UriKind.Absolute);

                    foreach (var key in res.Keys)
                    {
                        if (res[key] is string locString && locString.IsNullOrEmpty())
                        {
                            res.Remove(key);
                        }
                    }
                }
                catch (Exception ex)
                {
                    logger.Error(ex, $"PluginCommon - Failed to parse localization file {langFile}.");
                    return;
                }

                dictionaries.Add(res);
            }
            else
            {
                logger.Warn($"PluginCommon - File {langFile} not found.");
            }
        }