Theme code clean up

This commit is contained in:
Sean Kaim
2018-07-27 14:45:07 -04:00
parent 03d2387cdd
commit 9452d4dbe3
4 changed files with 152 additions and 244 deletions

View File

@@ -9,35 +9,14 @@ namespace mRemoteNG.Themes
/// </summary>
public class PseudoKeyColor
{
private string key;
private Color value;
public PseudoKeyColor(string _key, Color _value)
{
key = _key;
value = _value;
}
public string Key
{
get
{
return key;
}
set
{
key = value;
}
}
public Color Value
{
get
{
return value;
}
set
{
this.value = value;
}
Key = _key;
Value = _value;
}
public string Key { get; set; }
public Color Value { get; set; }
}
@@ -48,15 +27,14 @@ namespace mRemoteNG.Themes
{
#region Private Variables
//Collection for color values that are not loaded by dock panels (list, buttons,panel content, etc)
private Dictionary<string, Color> _extendedColors;
private Dictionary<string, Color> _default;
#endregion
#region Constructors
public ExtendedColorPalette()
{
_extendedColors = new Dictionary<string, Color>();
_default = new Dictionary<string, Color>(); // If this is the default palette, it will not have a default-default palette
ExtColorPalette = new Dictionary<string, Color>();
DefaultColorPalette = new Dictionary<string, Color>(); // If this is the default palette, it will not have a default-default palette
}
#endregion
@@ -65,7 +43,7 @@ namespace mRemoteNG.Themes
// Set the default theme, that theme should contain all color values used by the application
public void setDefault(ExtendedColorPalette inPalettte)
{
_default = inPalettte._extendedColors;
DefaultColorPalette = inPalettte.ExtColorPalette;
}
#endregion
@@ -76,12 +54,12 @@ namespace mRemoteNG.Themes
/// <returns></returns>
public Color getColor(string colorKey)
{
var retColor = _extendedColors.ContainsKey(colorKey) ? _extendedColors[colorKey]:Color.Empty;
var retColor = ExtColorPalette.ContainsKey(colorKey) ? ExtColorPalette[colorKey]:Color.Empty;
//Invisible colors are not good, might indicate missing color from the palette as is represented by 00000000
if (retColor != Color.Empty && retColor.A != 0) return retColor;
if(_default != null)
if(DefaultColorPalette != null)
{
retColor = _default.ContainsKey(colorKey) ? _default[colorKey] : Color.Empty;
retColor = DefaultColorPalette.ContainsKey(colorKey) ? DefaultColorPalette[colorKey] : Color.Empty;
}
//why are we here?, just avoid a crash
if(retColor == Color.Empty)
@@ -100,7 +78,7 @@ namespace mRemoteNG.Themes
/// <param name="inColor"></param>
public void addColor(string colorKey,Color inColor)
{
_extendedColors.Add(colorKey, inColor);
ExtColorPalette.Add(colorKey, inColor);
}
@@ -111,33 +89,13 @@ namespace mRemoteNG.Themes
/// <param name="inColor"></param>
public void replaceColor(string colorKey, Color inColor)
{
_extendedColors[colorKey]= inColor;
ExtColorPalette[colorKey]= inColor;
}
public Dictionary<string, Color> DefaultColorPalette
{
get
{
return _default;
}
set
{
_default = value;
}
}
public Dictionary<string, Color> DefaultColorPalette { get; set; }
public Dictionary<string, Color> ExtColorPalette
{
get
{
return _extendedColors;
}
set
{
_extendedColors = value;
}
}
public Dictionary<string, Color> ExtColorPalette { get; set; }
}
}

View File

@@ -7,6 +7,7 @@ using WeifenLuo.WinFormsUI.Docking;
namespace mRemoteNG.Themes
{
/// <inheritdoc />
/// <summary>
/// Container class for all the color and style elements to define a theme
/// </summary>
@@ -15,34 +16,32 @@ namespace mRemoteNG.Themes
#region Private Variables
private string _name;
private ThemeBase _theme;
private String _URI;
private string _URI;
private VisualStudioToolStripExtender.VsVersion _version;
private ExtendedColorPalette _extendedPalette;
private bool _isThemeBase;
private bool _isExtendable;
#endregion
#region Constructors
public ThemeInfo(string themeName, ThemeBase inTheme, String inURI, VisualStudioToolStripExtender.VsVersion inVersion, ExtendedColorPalette inExtendedPalette)
public ThemeInfo(string themeName, ThemeBase inTheme, string inURI, VisualStudioToolStripExtender.VsVersion inVersion, ExtendedColorPalette inExtendedPalette)
{
_name = themeName;
_theme = inTheme;
_URI = inURI;
_version = inVersion;
_extendedPalette = inExtendedPalette;
_isThemeBase = false;
_isExtendable = false;
IsThemeBase = false;
IsExtendable = false;
}
public ThemeInfo(string themeName, ThemeBase inTheme, String inURI, VisualStudioToolStripExtender.VsVersion inVersion)
public ThemeInfo(string themeName, ThemeBase inTheme, string inURI, VisualStudioToolStripExtender.VsVersion inVersion)
{
_name = themeName;
_theme = inTheme;
_URI = inURI;
_version = inVersion;
_isThemeBase = false;
_isExtendable = false;
IsThemeBase = false;
IsExtendable = false;
}
#endregion
@@ -57,8 +56,8 @@ namespace mRemoteNG.Themes
};
var clonedObj = new ThemeInfo(_name, _theme, _URI, _version, extPalette)
{
IsExtendable = _isExtendable,
IsThemeBase = _isThemeBase
IsExtendable = IsExtendable,
IsThemeBase = IsThemeBase
};
return clonedObj;
@@ -71,8 +70,8 @@ namespace mRemoteNG.Themes
[Browsable(false)]
public string Name
{
get { return _name; }
set
get => _name;
set
{
if (string.Equals(_name, value, StringComparison.InvariantCulture))
{
@@ -84,7 +83,7 @@ namespace mRemoteNG.Themes
public ThemeBase Theme
{
get { return _theme; }
get => _theme;
set
{
if (value != null && _theme == value)
@@ -97,7 +96,7 @@ namespace mRemoteNG.Themes
public string URI
{
get { return _URI; }
get => _URI;
set
{
if (value != null && _URI == value)
@@ -110,7 +109,7 @@ namespace mRemoteNG.Themes
public VisualStudioToolStripExtender.VsVersion Version
{
get { return _version; }
get => _version;
set
{
if (Equals(_version, value))
@@ -123,7 +122,7 @@ namespace mRemoteNG.Themes
public ExtendedColorPalette ExtendedPalette
{
get { return _extendedPalette; }
get => _extendedPalette;
set
{
if (_extendedPalette != null && _extendedPalette == value)
@@ -134,23 +133,10 @@ namespace mRemoteNG.Themes
}
}
public bool IsThemeBase
{
get { return _isThemeBase; }
set
{
_isThemeBase = value;
}
}
public bool IsThemeBase { get; set; }
public bool IsExtendable { get; set; }
public bool IsExtendable
{
get { return _isExtendable; }
set
{
_isExtendable = value;
}
}
#endregion
}
}

View File

@@ -46,11 +46,7 @@ namespace mRemoteNG.Themes
#region Public Methods
public static ThemeManager getInstance()
{
if(themeInstance == null)
{
themeInstance = new ThemeManager();
}
return themeInstance;
return themeInstance ?? (themeInstance = new ThemeManager());
}
@@ -64,80 +60,74 @@ namespace mRemoteNG.Themes
//THe manager precharges all the themes at once
public List<ThemeInfo> LoadThemes()
{
if (themes == null)
if (themes != null) return themes.Values.OfType<ThemeInfo>().ToList();
themes = new Hashtable();
//Load the files in theme folder first, to incluide vstheme light as default
var themePath = App.Info.SettingsFileInfo.ThemeFolder;
if (themePath == null) return themes.Values.OfType<ThemeInfo>().ToList();
try
{
themes = new Hashtable();
//Load the files in theme folder first, to incluide vstheme light as default
string themePath = App.Info.SettingsFileInfo.ThemeFolder;
if (themePath != null)
//In install mode first time is necesary to copy the themes folder
if (!Directory.Exists(themePath))
{
try
{
//In install mode first time is necesary to copy the themes folder
if (!Directory.Exists(themePath))
{
Directory.CreateDirectory(themePath);
Directory.CreateDirectory(themePath);
}
DirectoryInfo orig = new DirectoryInfo(App.Info.SettingsFileInfo.InstalledThemeFolder);
FileInfo[] files = orig.GetFiles();
foreach (FileInfo file in files)
{
}
var orig = new DirectoryInfo(App.Info.SettingsFileInfo.InstalledThemeFolder);
var files = orig.GetFiles();
foreach (var file in files)
{
if (!File.Exists(Path.Combine(themePath, file.Name)))
file.CopyTo(Path.Combine(themePath, file.Name), true);
}
//Check that theme folder exist before trying to load themes
if (Directory.Exists(themePath))
{
string[] themeFiles = Directory.GetFiles(themePath, "*.vstheme");
string defaultThemeURL = Directory.GetFiles(themePath, "vs2015light" + ".vstheme")[0];
//First we load the default theme, its vs2015light
ThemeInfo defaultTheme = ThemeSerializer.LoadFromXmlFile(defaultThemeURL);
themes.Add(defaultTheme.Name, defaultTheme);
//Then the rest
foreach (string themeFile in themeFiles)
{
//filter default one
ThemeInfo extTheme = ThemeSerializer.LoadFromXmlFile(themeFile, defaultTheme);
if (extTheme.Theme != null && !themes.ContainsKey(extTheme.Name))
{
themes.Add(extTheme.Name, extTheme);
}
}
//Load the embedded themes, extended palettes are taken from the vs2015 themes, trying to match the color theme
ThemeInfo vs2003 = new ThemeInfo("Vs2003", new VS2003Theme(), "", VisualStudioToolStripExtender.VsVersion.Vs2003, ((ThemeInfo)themes["vs2015light"]).ExtendedPalette);
themes.Add(vs2003.Name, vs2003);
ThemeInfo vs2005 = new ThemeInfo("Vs2005", new VS2005Theme(), "", VisualStudioToolStripExtender.VsVersion.Vs2005, ((ThemeInfo)themes["vs2015light"]).ExtendedPalette);
themes.Add(vs2005.Name, vs2005);
ThemeInfo vs2012Light = new ThemeInfo("vs2012Light", new VS2012LightTheme(), "", VisualStudioToolStripExtender.VsVersion.Vs2012, ((ThemeInfo)themes["vs2015light"]).ExtendedPalette);
themes.Add(vs2012Light.Name, vs2012Light);
ThemeInfo vs2012Dark = new ThemeInfo("vs2012Dark", new VS2012DarkTheme(), "", VisualStudioToolStripExtender.VsVersion.Vs2012, ((ThemeInfo)themes["vs2015dark"]).ExtendedPalette);
themes.Add(vs2012Dark.Name, vs2012Dark);
ThemeInfo vs2012Blue = new ThemeInfo("vs2012Blue", new VS2012BlueTheme(), "", VisualStudioToolStripExtender.VsVersion.Vs2012, ((ThemeInfo)themes["vs2015blue"]).ExtendedPalette);
themes.Add(vs2012Blue.Name, vs2012Blue);
ThemeInfo vs2013Light = new ThemeInfo("vs2013Light", new VS2013LightTheme(), "", VisualStudioToolStripExtender.VsVersion.Vs2013, ((ThemeInfo)themes["vs2015light"]).ExtendedPalette);
themes.Add(vs2013Light.Name, vs2013Light);
ThemeInfo vs2013Dark = new ThemeInfo("vs2013Dark", new VS2013DarkTheme(), "", VisualStudioToolStripExtender.VsVersion.Vs2013, ((ThemeInfo)themes["vs2015dark"]).ExtendedPalette);
themes.Add(vs2013Dark.Name, vs2013Dark);
ThemeInfo vs2013Blue = new ThemeInfo("vs2013Blue", new VS2013BlueTheme(), "", VisualStudioToolStripExtender.VsVersion.Vs2013, ((ThemeInfo)themes["vs2015blue"]).ExtendedPalette);
themes.Add(vs2013Blue.Name, vs2013Blue);
}
}
catch(Exception ex )
{
Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "Error loading themes" + Environment.NewLine + ex.Message, true);
}
if (!File.Exists(Path.Combine(themePath, file.Name)))
file.CopyTo(Path.Combine(themePath, file.Name), true);
}
}
//Check that theme folder exist before trying to load themes
if (Directory.Exists(themePath))
{
var themeFiles = Directory.GetFiles(themePath, "*.vstheme");
var defaultThemeURL = Directory.GetFiles(themePath, "vs2015light" + ".vstheme")[0];
//First we load the default theme, its vs2015light
var defaultTheme = ThemeSerializer.LoadFromXmlFile(defaultThemeURL);
themes.Add(defaultTheme.Name, defaultTheme);
//Then the rest
foreach (var themeFile in themeFiles)
{
//filter default one
var extTheme = ThemeSerializer.LoadFromXmlFile(themeFile, defaultTheme);
if (extTheme.Theme != null && !themes.ContainsKey(extTheme.Name))
{
themes.Add(extTheme.Name, extTheme);
}
}
//Load the embedded themes, extended palettes are taken from the vs2015 themes, trying to match the color theme
var vs2003 = new ThemeInfo("Vs2003", new VS2003Theme(), "", VisualStudioToolStripExtender.VsVersion.Vs2003, ((ThemeInfo)themes["vs2015light"]).ExtendedPalette);
themes.Add(vs2003.Name, vs2003);
var vs2005 = new ThemeInfo("Vs2005", new VS2005Theme(), "", VisualStudioToolStripExtender.VsVersion.Vs2005, ((ThemeInfo)themes["vs2015light"]).ExtendedPalette);
themes.Add(vs2005.Name, vs2005);
var vs2012Light = new ThemeInfo("vs2012Light", new VS2012LightTheme(), "", VisualStudioToolStripExtender.VsVersion.Vs2012, ((ThemeInfo)themes["vs2015light"]).ExtendedPalette);
themes.Add(vs2012Light.Name, vs2012Light);
var vs2012Dark = new ThemeInfo("vs2012Dark", new VS2012DarkTheme(), "", VisualStudioToolStripExtender.VsVersion.Vs2012, ((ThemeInfo)themes["vs2015dark"]).ExtendedPalette);
themes.Add(vs2012Dark.Name, vs2012Dark);
var vs2012Blue = new ThemeInfo("vs2012Blue", new VS2012BlueTheme(), "", VisualStudioToolStripExtender.VsVersion.Vs2012, ((ThemeInfo)themes["vs2015blue"]).ExtendedPalette);
themes.Add(vs2012Blue.Name, vs2012Blue);
var vs2013Light = new ThemeInfo("vs2013Light", new VS2013LightTheme(), "", VisualStudioToolStripExtender.VsVersion.Vs2013, ((ThemeInfo)themes["vs2015light"]).ExtendedPalette);
themes.Add(vs2013Light.Name, vs2013Light);
var vs2013Dark = new ThemeInfo("vs2013Dark", new VS2013DarkTheme(), "", VisualStudioToolStripExtender.VsVersion.Vs2013, ((ThemeInfo)themes["vs2015dark"]).ExtendedPalette);
themes.Add(vs2013Dark.Name, vs2013Dark);
var vs2013Blue = new ThemeInfo("vs2013Blue", new VS2013BlueTheme(), "", VisualStudioToolStripExtender.VsVersion.Vs2013, ((ThemeInfo)themes["vs2015blue"]).ExtendedPalette);
themes.Add(vs2013Blue.Name, vs2013Blue);
}
}
catch(Exception ex)
{
Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "Error loading themes" + Environment.NewLine + ex.Message, true);
}
return themes.Values.OfType<ThemeInfo>().ToList();
}
@@ -149,29 +139,24 @@ namespace mRemoteNG.Themes
/// <returns></returns>
public ThemeInfo addTheme(ThemeInfo baseTheme, string newThemeName)
{
if (!themes.Contains(newThemeName))
{
ThemeInfo modifiedTheme = (ThemeInfo)baseTheme.Clone();
modifiedTheme.Name = newThemeName;
modifiedTheme.IsExtendable = true;
modifiedTheme.IsThemeBase = false;
ThemeSerializer.SaveToXmlFile(modifiedTheme,baseTheme);
themes.Add(newThemeName,modifiedTheme);
return modifiedTheme;
}
return null;
if (themes.Contains(newThemeName)) return null;
var modifiedTheme = (ThemeInfo)baseTheme.Clone();
modifiedTheme.Name = newThemeName;
modifiedTheme.IsExtendable = true;
modifiedTheme.IsThemeBase = false;
ThemeSerializer.SaveToXmlFile(modifiedTheme,baseTheme);
themes.Add(newThemeName,modifiedTheme);
return modifiedTheme;
}
//Delete a theme from memory and disk
public void deleteTheme(ThemeInfo themeToDelete)
{
if (themes.Contains(themeToDelete.Name))
{
if(ActiveTheme == themeToDelete)
ActiveTheme = DefaultTheme;
themes.Remove(themeToDelete.Name);
ThemeSerializer.DeleteFile(themeToDelete);
}
if (!themes.Contains(themeToDelete.Name)) return;
if(ActiveTheme == themeToDelete)
ActiveTheme = DefaultTheme;
themes.Remove(themeToDelete.Name);
ThemeSerializer.DeleteFile(themeToDelete);
}
//Sincronize the theme XML values from memory to disk
@@ -191,10 +176,8 @@ namespace mRemoteNG.Themes
{
if (themes.Contains(name))
return false;
char[] badChars = Path.GetInvalidFileNameChars();
if (name.IndexOfAny(badChars) != -1)
return false;
return true;
var badChars = Path.GetInvalidFileNameChars();
return name.IndexOfAny(badChars) == -1;
}
@@ -206,10 +189,11 @@ namespace mRemoteNG.Themes
public event ThemeChangedEventHandler ThemeChanged
{
add { ThemeChangedEvent = (ThemeChangedEventHandler)System.Delegate.Combine(ThemeChangedEvent, value); }
remove { ThemeChangedEvent = (ThemeChangedEventHandler)System.Delegate.Remove(ThemeChangedEvent, value); }
add => ThemeChangedEvent = (ThemeChangedEventHandler)Delegate.Combine(ThemeChangedEvent, value);
remove => ThemeChangedEvent = (ThemeChangedEventHandler)Delegate.Remove(ThemeChangedEvent, value);
}
// ReSharper disable once UnusedParameter.Local
private void NotifyThemeChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "Name")
@@ -223,44 +207,28 @@ namespace mRemoteNG.Themes
#region Properties
public bool ThemingActive
{
get
{
return _themeActive;
}
get => _themeActive;
set
{
if(themes.Count != 0)
{
_themeActive = value;
Settings.Default.ThemingActive = value;
NotifyThemeChanged(this, new PropertyChangedEventArgs(""));
}
if (themes.Count == 0) return;
_themeActive = value;
Settings.Default.ThemingActive = value;
NotifyThemeChanged(this, new PropertyChangedEventArgs(""));
}
}
private ThemeInfo DefaultTheme
{
get
{
return (ThemeInfo) themes["vs2015light"];
}
}
private ThemeInfo DefaultTheme => (ThemeInfo) themes["vs2015light"];
public ThemeInfo ActiveTheme
{
get
{
return _activeTheme;
}
set
get => _activeTheme;
set
{
//You can only enable theming if there are themes laoded
if(value != null)
{
_activeTheme = value;
Settings.Default.ThemeName = value.Name;
NotifyThemeChanged(this, new PropertyChangedEventArgs("theme"));
}
if (value == null) return;
_activeTheme = value;
Settings.Default.ThemeName = value.Name;
NotifyThemeChanged(this, new PropertyChangedEventArgs("theme"));
}
}
#endregion

View File

@@ -1,25 +1,22 @@
using System.Collections.Generic;
using System;
using System.Drawing;
using System.IO;
using System.Xml;
using WeifenLuo.WinFormsUI.Docking;
using System.Linq;
namespace mRemoteNG.Themes
{
public class ThemeSerializer
public static class ThemeSerializer
{
/// <summary>
/// Save the theme to file, name property is used as filename
/// The baseTheme is used as a template, by copy that file and rewrite the extpalette values
/// </summary>
/// <param name="themeInfo"></param>
public static void SaveToXmlFile(ThemeInfo themeToSave,ThemeInfo baseTheme)
/// <summary>
/// Save the theme to file, name property is used as filename
/// The baseTheme is used as a template, by copy that file and rewrite the extpalette values
/// </summary>
/// <param name="themeToSave"></param>
/// <param name="baseTheme"></param>
public static void SaveToXmlFile(ThemeInfo themeToSave,ThemeInfo baseTheme)
{
string oldURI = baseTheme.URI;
String directoryName = Path.GetDirectoryName(oldURI);
string toSaveURI = directoryName + Path.DirectorySeparatorChar + themeToSave.Name + ".vstheme";
var oldURI = baseTheme.URI;
var directoryName = Path.GetDirectoryName(oldURI);
var toSaveURI = directoryName + Path.DirectorySeparatorChar + themeToSave.Name + ".vstheme";
File.Copy(baseTheme.URI, toSaveURI);
themeToSave.URI = toSaveURI;
}
@@ -35,10 +32,9 @@ namespace mRemoteNG.Themes
/// <param name="themeToUpdate"></param>
public static void UpdateThemeXMLValues(ThemeInfo themeToUpdate)
{
byte[] bytesIn = File.ReadAllBytes(themeToUpdate.URI);
MremoteNGPaletteManipulator manipulator;
manipulator = new MremoteNGPaletteManipulator(bytesIn, themeToUpdate.ExtendedPalette);
byte[] bytesOut = manipulator.mergePalette(themeToUpdate.ExtendedPalette);
var bytesIn = File.ReadAllBytes(themeToUpdate.URI);
var manipulator = new MremoteNGPaletteManipulator(bytesIn, themeToUpdate.ExtendedPalette);
var bytesOut = manipulator.mergePalette(themeToUpdate.ExtendedPalette);
File.WriteAllBytes(themeToUpdate.URI, bytesOut);
}
@@ -50,22 +46,22 @@ namespace mRemoteNG.Themes
/// <returns></returns>
public static ThemeInfo LoadFromXmlFile(string filename, ThemeInfo defaultTheme=null)
{
byte[] bytes = File.ReadAllBytes(filename);
var bytes = File.ReadAllBytes(filename);
//Load the dockpanel part
MremoteNGThemeBase themeBaseLoad= new MremoteNGThemeBase(bytes);
var themeBaseLoad= new MremoteNGThemeBase(bytes);
//Load the mremote part
MremoteNGPaletteManipulator extColorLoader;
//Cause we cannot default the theme for the default theme
extColorLoader = new MremoteNGPaletteManipulator(bytes, defaultTheme ==null ? null:defaultTheme.ExtendedPalette);
ThemeInfo loadedTheme = new ThemeInfo(Path.GetFileNameWithoutExtension(filename), themeBaseLoad, filename, VisualStudioToolStripExtender.VsVersion.Vs2015, extColorLoader.getColors());
if((new string[] { "darcula", "vs2015blue", "vs2015dark" , "vs2015light" }).Contains(Path.GetFileNameWithoutExtension(filename)))
//Cause we cannot default the theme for the default theme
var extColorLoader = new MremoteNGPaletteManipulator(bytes, defaultTheme?.ExtendedPalette);
var loadedTheme = new ThemeInfo(Path.GetFileNameWithoutExtension(filename), themeBaseLoad, filename, VisualStudioToolStripExtender.VsVersion.Vs2015, extColorLoader.getColors());
if(new[] { "darcula", "vs2015blue", "vs2015dark" , "vs2015light" }.Contains(Path.GetFileNameWithoutExtension(filename)))
{
loadedTheme.IsThemeBase = true;
}
loadedTheme.IsExtendable = true;
return loadedTheme;
}
/*
private static string EncodeColorName(Color color)
{
// best/simplest answer to converting to hex: http://stackoverflow.com/questions/12078942/how-to-convert-from-argb-to-hex-aarrggbb
@@ -77,7 +73,7 @@ namespace mRemoteNG.Themes
var regex = new System.Text.RegularExpressions.Regex("^[0-9a-fA-F]{8}$");
return regex.Match(name).Success ? Color.FromArgb(Convert.ToInt32(name, 16)) : Color.FromName(name);
}
*/
}
}