public ThemeEditDialogViewModel(ThemesWindowViewModel themesWindowViewModel, Theme.Factory themeFactory) { _themesWindowViewModel = themesWindowViewModel; _themeFactory = themeFactory; SaveCommand = new RelayCommand(SaveExecute, SaveCanExecute); CancelCommand = new RelayCommand(CancelExecute); }
/// <summary> /// Initializes a new instance of the <see cref="T:System.Object"/> class. /// </summary> public ThemeManager(ILogger logger, Settings settings, Theme.FactoryFromConfig themeFromConfig, Theme.FactoryFromPath themeFromPath) { _logger = logger; _themeFromConfig = themeFromConfig; _themeFromPath = themeFromPath; _settings = settings; }
public void TestLoad() { var theme = new Theme(); theme.LoadFromPath(_themePath); // Assert the loaded theme has expected values foreach (var field in _themeDict) { Assert.That(theme.Config[field.Key], Is.EqualTo(field.Value)); } }
/// <summary> /// Applys the theme by modifying App Resources. /// </summary> /// <remarks>This method is called heavily by the theme editor.</remarks> /// <param name="theme">The theme.</param> public void ApplyTheme(Theme theme) { // convert theme to ResourceDictionary var themeResourceDictionary = theme.ToResourceDictionary(); var mergedDictionaries = Application.Current.Resources.MergedDictionaries; // need to remove the last theme resource dictionary if (ActiveTheme != null) { mergedDictionaries.RemoveAt(mergedDictionaries.Count - 1); } Application.Current.Resources.MergedDictionaries.Add(themeResourceDictionary); ActiveTheme = theme; }
public void TestDelete() { // copy test theme var copyPath = Path.GetTempFileName(); File.Copy(_themePath, copyPath, true); // load the copy var theme = new Theme(); theme.LoadFromPath(copyPath); // delete theme.Delete(); // assert the file does not exist Assert.That(File.Exists(copyPath), Is.False); }
/// <summary> /// Duplicates <paramref name="theme" />. /// </summary> /// <param name="theme">The theme.</param> public void DuplicateTheme(Theme theme) { var clone = theme.Duplicate(); clone.Save(); ThemeManager.RegisterTheme(clone); SelectItemByModel(clone); }
/// <summary> /// Show a yes/no dialog that offers deletion of <paramref name="theme" /> /// </summary> /// <param name="theme">The theme.</param> public void DeleteTheme(Theme theme) { if (!theme.Editable) { return; } var result = _dialogService.Messagebox("Remove currently selected theme?", "Delete Theme", MessageBoxButton.YesNo); if (result == MessageBoxResult.Yes) { var idx = Items.IndexOf(SelectedItem); // delete the theme theme.Delete(); // unregister the theme ThemeManager.UnregisterTheme(theme); // select another theme if (Items.Any()) { SelectedItem = Items[--idx]; } else { SelectedItem = null; } FocusSelectedItem(); } }
/// <summary> /// Unregister the theme. /// </summary> /// <param name="theme">The theme.</param> public void UnregisterTheme(Theme theme) { Themes.Remove(theme); }
/// <summary> /// Register the theme, so it is available to parts of the application. /// </summary> /// <param name="theme">The theme.</param> /// <exception cref="ThemeGuidAlreadyExists">The theme name is already registered</exception> public void RegisterTheme(Theme theme) { try { // check if Guid is already registered if (Themes.Any(t => t.Guid == theme.Guid)) { // todo: instead of crash, maybe we should just skip the theme throw new ThemeGuidAlreadyExists(theme.Guid); } Themes.Add(theme); } catch { // ignored } }
/// <summary> /// Initializes the default (fallback) theme, which is used when no theme is loaded. /// Also if a theme doesn't specify a color, the color from this theme is used. /// </summary> public void InitializeDefaultTheme() { // load the default theme json from Resources var path = new Uri("Themes/default.json", UriKind.Relative); var resource = Application.GetResourceStream(path); var reader = new StreamReader(resource.Stream); var json = reader.ReadToEnd(); // parse the json and load into a Theme object dynamic result = JsonConvert.DeserializeObject(json); Dictionary<string, string> config = result.ToObject<Dictionary<string, string>>(); DefaultTheme = _themeFromConfig(config); // insert the resource dictionary to application resources var mergedDictionaries = Application.Current.Resources.MergedDictionaries; mergedDictionaries[1].MergedDictionaries[0] = DefaultTheme.ToResourceDictionary(); }
public void TestLoadParseException() { // create new file var corruptThemePath = Path.GetTempFileName(); // load the test theme file, and write a corrupt version var contents = File.ReadAllText(_themePath); contents = contents.Replace("{", "!!!"); File.WriteAllText(corruptThemePath, contents); // assert that loading causes exception Assert.That(() => { var theme = new Theme(); theme.LoadFromPath(corruptThemePath); }, Throws.Exception.TypeOf<JsonReaderException>()); }
public void TestSave() { // load test theme var theme = new Theme(); theme.LoadFromPath(_themePath); // export to another path var themeSavePath = Path.GetTempFileName(); theme.Save(themeSavePath); // load the export var exportedTheme = new Theme(); exportedTheme.LoadFromPath(themeSavePath); // Assert the loaded theme has expected values foreach (var field in _themeDict) { Assert.That(theme.Config[field.Key], Is.EqualTo(field.Value)); } }
public void TestResourceDictionary() { var theme = new Theme(); theme.LoadFromPath(_themePath); var resourceDictionary = theme.ToResourceDictionary(); // test the resource dictionary for correctness by comparing each color foreach (var colorKey in _colorKeys) { var actualColor = ((SolidColorBrush) resourceDictionary[colorKey]).Color; var expectedColor = ((SolidColorBrush) new BrushConverter().ConvertFromString(_themeDict[colorKey])).Color; Assert.That(actualColor, Is.EqualTo(expectedColor)); } }
public void TestLoadWithBadPath() { var theme = new Theme(); var randomPath = Path.Combine("c:\\", Path.GetRandomFileName()); Assert.Throws<FileNotFoundException>(() => theme.LoadFromPath(randomPath)); }
/// <summary> /// Show a save file dialog that will offer to export <paramref name="theme" /> to a .json file. /// </summary> public void ExportTheme(Theme theme) { var filename = _dialogService.SaveFileDialog(".json", "JSON themes|*.json", theme.Name); if (!string.IsNullOrEmpty(filename)) { theme.Save(filename); SelectItemByModel(theme); } }
/// <summary> /// Register the theme, so it is available to parts of the application. /// </summary> /// <param name="theme">The theme.</param> /// <exception cref="ThemeGuidAlreadyExists">The theme name is already registered</exception> public void RegisterTheme(Theme theme) { // check if Guid is already registered if (Themes.Any(t => t.Guid == theme.Guid)) { _logger.Debug(new ThemeGuidAlreadyExists(theme.Guid)); } else { Themes.Add(theme); } }
public void SelectItemByModel(Theme model) { SelectedItem = Items.First(t => t.Model == model); FocusSelectedItem(); }
/// <summary> /// Sets the theme to be edited. /// We store a reference to the original theme, and create a clone for our editing purposes. /// </summary> public void SetTheme(Theme originalTheme) { // close any popups HideColorPicker(); // store reference to original theme _originalTheme = originalTheme; // create a clone _editedTheme = originalTheme.Clone(); // apply the clone _themeManager.ApplyTheme(_editedTheme); _themeManager.SaveSettings(); // editor state is unchanged (no cancel or save buttons shown) HasChanged = false; }