From 9f09798da59d08804c0fd01883c33b5a8e177c11 Mon Sep 17 00:00:00 2001 From: Riley McArdle Date: Thu, 14 Mar 2013 19:46:06 -0500 Subject: [PATCH] More theme improvements. --- mRemoteV1/App/App.Runtime.vb | 2 - mRemoteV1/Config/Theme.vb | 314 ------------------ mRemoteV1/Forms/frmMain.vb | 64 ++-- mRemoteV1/Forms/frmOptions.vb | 136 +++----- mRemoteV1/Themes/ThemeInfo.vb | 308 +++++++++++++++++ mRemoteV1/Themes/ThemeManager.vb | 69 ++++ .../{Config => Themes}/ThemeSerializer.vb | 34 +- mRemoteV1/UI/UI.Window.Config.vb | 20 +- mRemoteV1/UI/UI.Window.Tree.vb | 24 +- mRemoteV1/mRemoteV1.vbproj | 5 +- 10 files changed, 505 insertions(+), 471 deletions(-) delete mode 100644 mRemoteV1/Config/Theme.vb create mode 100644 mRemoteV1/Themes/ThemeInfo.vb create mode 100644 mRemoteV1/Themes/ThemeManager.vb rename mRemoteV1/{Config => Themes}/ThemeSerializer.vb (80%) diff --git a/mRemoteV1/App/App.Runtime.vb b/mRemoteV1/App/App.Runtime.vb index c60835ac..5f4015e8 100644 --- a/mRemoteV1/App/App.Runtime.vb +++ b/mRemoteV1/App/App.Runtime.vb @@ -261,8 +261,6 @@ Namespace App Public Shared AnnouncementForm As UI.Window.Announcement Public Shared AnnouncementPanel As New DockContent - Public Shared Property Theme As New Config.Theme - Public Shared Sub Show(ByVal windowType As UI.Window.Type, Optional ByVal portScanMode As PortScan.PortScanMode = PortScan.PortScanMode.Normal) Try Select Case windowType diff --git a/mRemoteV1/Config/Theme.vb b/mRemoteV1/Config/Theme.vb deleted file mode 100644 index 45603eaa..00000000 --- a/mRemoteV1/Config/Theme.vb +++ /dev/null @@ -1,314 +0,0 @@ -Imports System.ComponentModel - -Namespace Config - Public Class Theme -#Region "Public Methods" - Public Sub FromTheme(ByVal theme As Theme) - BeginUpdate() - - Name = theme.Name - - Dim themeType As Type = (New Theme).GetType() - Dim colorType As Type = (New Color).GetType() - Dim color As Color - For Each propertyInfo As Reflection.PropertyInfo In themeType.GetProperties() - If Not propertyInfo.PropertyType Is colorType Then Continue For - color = propertyInfo.GetValue(theme, Nothing) - propertyInfo.SetValue(Me, color, Nothing) - Next - - EndUpdate() - End Sub - - Public Sub BeginUpdate() - _inUpdate = True - End Sub - - Public Sub EndUpdate() - _inUpdate = False - RaiseThemeChanged() - End Sub -#End Region - -#Region "Events" - Public Event ThemeChanged() - Protected Sub RaiseThemeChanged() - If Not _inUpdate Then RaiseEvent ThemeChanged() - End Sub -#End Region - -#Region "Private Fields" - Private _inUpdate As Boolean = vbFalse -#End Region - -#Region "Properties" - _ - Public Property Name As String = "Unnamed Theme" - -#Region "General" - Private _windowBackground As Color = SystemColors.AppWorkspace - _ - Public Property WindowBackground() As Color - Get - Return (_windowBackground) - End Get - Set(value As Color) - If _windowBackground = value Then Return - _windowBackground = value - RaiseThemeChanged() - End Set - End Property - - Private _menuBackground As Color = SystemColors.Control - - Public Property MenuBackground() As Color - Get - Return _menuBackground - End Get - Set(value As Color) - If _menuBackground = value Then Return - _menuBackground = value - RaiseThemeChanged() - End Set - End Property - - Private _menuText As Color = SystemColors.ControlText - - Public Property MenuText() As Color - Get - Return _menuText - End Get - Set(value As Color) - If _menuText = value Then Return - _menuText = value - RaiseThemeChanged() - End Set - End Property - - Private _toolbarBackground As Color = SystemColors.Control - _ - Public Property ToolbarBackground() As Color - Get - Return _toolbarBackground - End Get - Set(value As Color) - If _toolbarBackground = value Then Return - _toolbarBackground = value - RaiseThemeChanged() - End Set - End Property - - Private _toolbarText As Color = SystemColors.ControlText - _ - Public Property ToolbarText() As Color - Get - Return _toolbarText - End Get - Set(value As Color) - If _toolbarText = value Then Return - _toolbarText = value - RaiseThemeChanged() - End Set - End Property -#End Region - -#Region "Connections Panel" - Private _connectionsPanelBackground As Color = SystemColors.Window - _ - Public Property ConnectionsPanelBackground() As Color - Get - Return _connectionsPanelBackground - End Get - Set(value As Color) - If _connectionsPanelBackground = value Or value = Color.Transparent Then Return - _connectionsPanelBackground = value - RaiseThemeChanged() - End Set - End Property - - Private _connectionsPanelText As Color = SystemColors.WindowText - - Public Property ConnectionsPanelText() As Color - Get - Return _connectionsPanelText - End Get - Set(value As Color) - If _connectionsPanelText = value Then Return - _connectionsPanelText = value - RaiseThemeChanged() - End Set - End Property - - Private _connectionsPanelTreeLines As Color = Color.Black - - Public Property ConnectionsPanelTreeLines() As Color - Get - Return _connectionsPanelTreeLines - End Get - Set(value As Color) - If _connectionsPanelTreeLines = value Then Return - _connectionsPanelTreeLines = value - RaiseThemeChanged() - End Set - End Property - - Private _searchBoxBackground As Color = SystemColors.Window - _ - Public Property SearchBoxBackground() As Color - Get - Return _searchBoxBackground - End Get - Set(value As Color) - If _searchBoxBackground = value Or value = Color.Transparent Then Return - _searchBoxBackground = value - RaiseThemeChanged() - End Set - End Property - - Private _searchBoxTextPrompt As Color = SystemColors.GrayText - _ - Public Property SearchBoxTextPrompt() As Color - Get - Return _searchBoxTextPrompt - End Get - Set(value As Color) - If _searchBoxTextPrompt = value Then Return - _searchBoxTextPrompt = value - RaiseThemeChanged() - End Set - End Property - - Private _searchBoxText As Color = SystemColors.WindowText - _ - Public Property SearchBoxText() As Color - Get - Return _searchBoxText - End Get - Set(value As Color) - If _searchBoxText = value Then Return - _searchBoxText = value - RaiseThemeChanged() - End Set - End Property -#End Region - -#Region "Config Panel" - Private _configPanelBackground As Color = SystemColors.Window - _ - Public Property ConfigPanelBackground() As Color - Get - Return _configPanelBackground - End Get - Set(value As Color) - If _configPanelBackground = value Or value = Color.Transparent Then Return - _configPanelBackground = value - RaiseThemeChanged() - End Set - End Property - - Private _configPanelText As Color = SystemColors.WindowText - _ - Public Property ConfigPanelText() As Color - Get - Return _configPanelText - End Get - Set(value As Color) - If _configPanelText = value Then Return - _configPanelText = value - RaiseThemeChanged() - End Set - End Property - - Private _configPanelCategoryText As Color = SystemColors.ControlText - _ - Public Property ConfigPanelCategoryText() As Color - Get - Return _configPanelCategoryText - End Get - Set(value As Color) - If _configPanelCategoryText = value Then Return - _configPanelCategoryText = value - RaiseThemeChanged() - End Set - End Property - - Private _configPanelHelpBackground As Color = SystemColors.Control - _ - Public Property ConfigPanelHelpBackground() As Color - Get - Return _configPanelHelpBackground - End Get - Set(value As Color) - If _configPanelHelpBackground = value Or value = Color.Transparent Then Return - _configPanelHelpBackground = value - RaiseThemeChanged() - End Set - End Property - - Private _configPanelHelpText As Color = SystemColors.ControlText - _ - Public Property ConfigPanelHelpText() As Color - Get - Return _configPanelHelpText - End Get - Set(value As Color) - If _configPanelHelpText = value Then Return - _configPanelHelpText = value - RaiseThemeChanged() - End Set - End Property - - Private _configPanelGridLines As Color = SystemColors.InactiveBorder - _ - Public Property ConfigPanelGridLines() As Color - Get - Return _configPanelGridLines - End Get - Set(value As Color) - If _configPanelGridLines = value Then Return - _configPanelGridLines = value - RaiseThemeChanged() - End Set - End Property -#End Region -#End Region - End Class -End Namespace diff --git a/mRemoteV1/Forms/frmMain.vb b/mRemoteV1/Forms/frmMain.vb index a465e9e8..fe5aa13d 100644 --- a/mRemoteV1/Forms/frmMain.vb +++ b/mRemoteV1/Forms/frmMain.vb @@ -7,6 +7,7 @@ Imports Crownwood Imports mRemoteNG.App.Native Imports PSTaskDialog Imports mRemoteNG.Config +Imports mRemoteNG.Themes Public Class frmMain Private _previousWindowState As FormWindowState @@ -36,6 +37,14 @@ Public Class frmMain Startup.CreateLogger() + Try + ThemeManager.LoadThemes() + ThemeManager.ActiveTheme = ThemeManager.DefaultTheme + AddHandler ThemeManager.ThemeChanged, AddressOf ApplyThemes + Catch ex As Exception + Debug.Print(ex.Message) + End Try + ' Create gui config load and save objects Dim SettingsLoad As New Config.Settings.Load(Me) @@ -47,14 +56,7 @@ Public Class frmMain Startup.ParseCommandLineArgs() ApplyLanguage() - - Try - AddHandler Windows.Theme.ThemeChanged, AddressOf ApplyThemes - Dim themes As List(Of Theme) = ThemeSerializer.LoadFromXmlFile(Path.Combine(App.Info.Settings.SettingsPath, App.Info.Settings.ThemesFileName)) - If themes.Count Then Windows.Theme.FromTheme(themes(0)) - Catch ex As Exception - Debug.Print(ex.Message) - End Try + ApplyThemes() fpChainedWindowHandle = SetClipboardViewer(Me.Handle) @@ -177,36 +179,36 @@ Public Class frmMain End Sub Public Sub ApplyThemes() - With Windows.Theme - pnlDock.DockBackColor = .WindowBackground - tsContainer.BackColor = .ToolbarBackground - tsContainer.ForeColor = .ToolbarText - tsContainer.TopToolStripPanel.BackColor = .ToolbarBackground - tsContainer.TopToolStripPanel.ForeColor = .ToolbarText - tsContainer.BottomToolStripPanel.BackColor = .ToolbarBackground - tsContainer.BottomToolStripPanel.ForeColor = .ToolbarText - tsContainer.LeftToolStripPanel.BackColor = .ToolbarBackground - tsContainer.LeftToolStripPanel.ForeColor = .ToolbarText - tsContainer.RightToolStripPanel.BackColor = .ToolbarBackground - tsContainer.RightToolStripPanel.ForeColor = .ToolbarText - tsContainer.ContentPanel.BackColor = .ToolbarBackground - tsContainer.ContentPanel.ForeColor = .ToolbarText - msMain.BackColor = .ToolbarBackground - msMain.ForeColor = .ToolbarText + With ThemeManager.ActiveTheme + pnlDock.DockBackColor = .WindowBackgroundColor + tsContainer.BackColor = .ToolbarBackgroundColor + tsContainer.ForeColor = .ToolbarTextColor + tsContainer.TopToolStripPanel.BackColor = .ToolbarBackgroundColor + tsContainer.TopToolStripPanel.ForeColor = .ToolbarTextColor + tsContainer.BottomToolStripPanel.BackColor = .ToolbarBackgroundColor + tsContainer.BottomToolStripPanel.ForeColor = .ToolbarTextColor + tsContainer.LeftToolStripPanel.BackColor = .ToolbarBackgroundColor + tsContainer.LeftToolStripPanel.ForeColor = .ToolbarTextColor + tsContainer.RightToolStripPanel.BackColor = .ToolbarBackgroundColor + tsContainer.RightToolStripPanel.ForeColor = .ToolbarTextColor + tsContainer.ContentPanel.BackColor = .ToolbarBackgroundColor + tsContainer.ContentPanel.ForeColor = .ToolbarTextColor + msMain.BackColor = .ToolbarBackgroundColor + msMain.ForeColor = .ToolbarTextColor ApplyMenuColors(msMain.Items) - tsExternalTools.BackColor = .ToolbarBackground - tsExternalTools.ForeColor = .ToolbarText - tsQuickConnect.BackColor = .ToolbarBackground - tsQuickConnect.ForeColor = .ToolbarText + tsExternalTools.BackColor = .ToolbarBackgroundColor + tsExternalTools.ForeColor = .ToolbarTextColor + tsQuickConnect.BackColor = .ToolbarBackgroundColor + tsQuickConnect.ForeColor = .ToolbarTextColor End With End Sub Private Sub ApplyMenuColors(itemCollection As ToolStripItemCollection) - With Windows.Theme + With ThemeManager.ActiveTheme Dim menuItem As ToolStripMenuItem For Each item As ToolStripItem In itemCollection - item.BackColor = .MenuBackground - item.ForeColor = .MenuText + item.BackColor = .MenuBackgroundColor + item.ForeColor = .MenuTextColor menuItem = TryCast(item, ToolStripMenuItem) If menuItem IsNot Nothing Then diff --git a/mRemoteV1/Forms/frmOptions.vb b/mRemoteV1/Forms/frmOptions.vb index 51353fca..08a33564 100644 --- a/mRemoteV1/Forms/frmOptions.vb +++ b/mRemoteV1/Forms/frmOptions.vb @@ -1,7 +1,9 @@ Imports System.IO +Imports System.ComponentModel Imports mRemoteNG.My Imports WeifenLuo.WinFormsUI.Docking Imports mRemoteNG.App.Runtime +Imports mRemoteNG.Themes Public Class frmOptions Inherits System.Windows.Forms.Form @@ -119,7 +121,7 @@ Public Class frmOptions Friend WithEvents tabTheme As System.Windows.Forms.TabPage Friend WithEvents ThemePropertyGrid As System.Windows.Forms.PropertyGrid Friend WithEvents dlgColor As System.Windows.Forms.ColorDialog - Friend WithEvents btnThemeSave As System.Windows.Forms.Button + Friend WithEvents btnThemeNew As System.Windows.Forms.Button Friend WithEvents cboTheme As System.Windows.Forms.ComboBox Friend WithEvents btnThemeDelete As System.Windows.Forms.Button Private components As System.ComponentModel.IContainer @@ -246,7 +248,7 @@ Public Class frmOptions Me.tabAdvanced = New System.Windows.Forms.TabPage() Me.tabTheme = New System.Windows.Forms.TabPage() Me.btnThemeDelete = New System.Windows.Forms.Button() - Me.btnThemeSave = New System.Windows.Forms.Button() + Me.btnThemeNew = New System.Windows.Forms.Button() Me.cboTheme = New System.Windows.Forms.ComboBox() Me.ThemePropertyGrid = New System.Windows.Forms.PropertyGrid() Me.dlgColor = New System.Windows.Forms.ColorDialog() @@ -1441,7 +1443,7 @@ Public Class frmOptions 'tabTheme ' Me.tabTheme.Controls.Add(Me.btnThemeDelete) - Me.tabTheme.Controls.Add(Me.btnThemeSave) + Me.tabTheme.Controls.Add(Me.btnThemeNew) Me.tabTheme.Controls.Add(Me.cboTheme) Me.tabTheme.Controls.Add(Me.ThemePropertyGrid) Me.tabTheme.Location = New System.Drawing.Point(4, 22) @@ -1454,28 +1456,28 @@ Public Class frmOptions ' 'btnThemeDelete ' - Me.btnThemeDelete.Location = New System.Drawing.Point(521, 5) + Me.btnThemeDelete.Location = New System.Drawing.Point(524, 5) Me.btnThemeDelete.Name = "btnThemeDelete" Me.btnThemeDelete.Size = New System.Drawing.Size(75, 23) Me.btnThemeDelete.TabIndex = 2 Me.btnThemeDelete.Text = "&Delete" Me.btnThemeDelete.UseVisualStyleBackColor = True ' - 'btnThemeSave + 'btnThemeNew ' - Me.btnThemeSave.Location = New System.Drawing.Point(440, 5) - Me.btnThemeSave.Name = "btnThemeSave" - Me.btnThemeSave.Size = New System.Drawing.Size(75, 23) - Me.btnThemeSave.TabIndex = 1 - Me.btnThemeSave.Text = "&Save" - Me.btnThemeSave.UseVisualStyleBackColor = True + Me.btnThemeNew.Location = New System.Drawing.Point(443, 5) + Me.btnThemeNew.Name = "btnThemeNew" + Me.btnThemeNew.Size = New System.Drawing.Size(75, 23) + Me.btnThemeNew.TabIndex = 1 + Me.btnThemeNew.Text = "&New" + Me.btnThemeNew.UseVisualStyleBackColor = True ' 'cboTheme ' Me.cboTheme.FormattingEnabled = True - Me.cboTheme.Location = New System.Drawing.Point(6, 7) + Me.cboTheme.Location = New System.Drawing.Point(3, 7) Me.cboTheme.Name = "cboTheme" - Me.cboTheme.Size = New System.Drawing.Size(428, 21) + Me.cboTheme.Size = New System.Drawing.Size(434, 21) Me.cboTheme.TabIndex = 0 ' 'ThemePropertyGrid @@ -1665,15 +1667,14 @@ Public Class frmOptions Me.txtXULrunnerPath.Text = My.Settings.XULRunnerPath - _themes = Config.ThemeSerializer.LoadFromXmlFile(Path.Combine(App.Info.Settings.SettingsPath, App.Info.Settings.ThemesFileName)) - cboTheme.DisplayMember = "Name" - cboTheme.Items.Add(_defaultTheme) - For Each theme As Config.Theme In _themes - cboTheme.Items.Add(theme) - Next - cboTheme.Text = Windows.Theme.Name + _themeList = New BindingList(Of ThemeInfo)(ThemeManager.LoadThemes()) + cboTheme.DataSource = _themeList + cboTheme.SelectedItem = ThemeManager.ActiveTheme cboTheme_SelectionChangeCommitted(Me, New EventArgs()) + ThemePropertyGrid.PropertySort = PropertySort.Categorized + + _originalTheme = ThemeManager.ActiveTheme Catch ex As Exception MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "LoadOptions (UI.Window.Options) failed" & vbNewLine & ex.Message, True) End Try @@ -1800,7 +1801,7 @@ Public Class frmOptions My.Settings.XULRunnerPath = Me.txtXULrunnerPath.Text - btnThemeSave_Click(Me, New EventArgs()) + ThemeManager.SaveThemes(_themeList) If My.Settings.LoadConsFromCustomLocation = False Then App.Runtime.SetMainFormText(App.Info.Connections.DefaultConnectionsPath & "\" & App.Info.Connections.DefaultConnectionsFile) @@ -1822,8 +1823,8 @@ Public Class frmOptions #Region "Private Variables" Private _initialTab As Integer = 0 - Private _themes As List(Of Config.Theme) - Private ReadOnly _defaultTheme As New Config.Theme + Private _themeList As BindingList(Of ThemeInfo) + Private _originalTheme As ThemeInfo #End Region #Region "Public Methods" @@ -1853,9 +1854,6 @@ Public Class frmOptions End If Next #End If - - ThemePropertyGrid.PropertySort = PropertySort.Categorized - ThemePropertyGrid.SelectedObject = Windows.Theme End Sub Private Sub ApplyLanguage() @@ -1943,8 +1941,6 @@ Public Class frmOptions chkEncryptCompleteFile.Text = My.Language.strEncryptCompleteConnectionFile lblLanguage.Text = My.Language.strLanguage lblLanguageRestartRequired.Text = String.Format(My.Language.strLanguageRestartRequired, My.Application.Info.ProductName) - - _defaultTheme.Name = "(Default Theme)" End Sub Public Shadows Sub Show(ByVal dockPanel As DockPanel, Optional ByVal initialTab As Integer = 0) @@ -1954,8 +1950,9 @@ Public Class frmOptions MyBase.ShowDialog(frmMain) End Sub - Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click - Me.Close() + Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As EventArgs) Handles btnCancel.Click + ThemeManager.ActiveTheme = _originalTheme + Close() End Sub Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click @@ -2082,76 +2079,49 @@ Public Class frmOptions End If End Sub - Private Sub cboTheme_TextChanged(ByVal sender As Object, ByVal e As EventArgs) Handles cboTheme.TextChanged - If cboTheme.Text = "" Or cboTheme.Text = _defaultTheme.Name Then - btnThemeSave.Enabled = False - btnThemeDelete.Enabled = False - Else - btnThemeSave.Enabled = True - btnThemeDelete.Enabled = True - Windows.Theme.Name = cboTheme.Text - End If + Private Sub cboTheme_DropDown(ByVal sender As Object, ByVal e As EventArgs) Handles cboTheme.DropDown, cboTheme.LostFocus + If ThemeManager.ActiveTheme Is ThemeManager.DefaultTheme Then Return + ThemeManager.ActiveTheme.Name = cboTheme.Text End Sub Private Sub cboTheme_SelectionChangeCommitted(ByVal sender As Object, ByVal e As EventArgs) Handles cboTheme.SelectionChangeCommitted ', cboTheme.SelectedIndexChanged, cboTheme.SelectedValueChanged - If cboTheme.SelectedItem Is Nothing OrElse cboTheme.SelectedItem Is _defaultTheme Then - btnThemeSave.Enabled = False + If cboTheme.SelectedItem Is Nothing Then cboTheme.SelectedItem = ThemeManager.DefaultTheme + + If cboTheme.SelectedItem Is ThemeManager.DefaultTheme Then + cboTheme.DropDownStyle = ComboBoxStyle.DropDownList btnThemeDelete.Enabled = False + ThemePropertyGrid.Enabled = False Else - btnThemeSave.Enabled = True + cboTheme.DropDownStyle = ComboBoxStyle.DropDown btnThemeDelete.Enabled = True + ThemePropertyGrid.Enabled = True End If - If cboTheme.SelectedItem Is Nothing Then Return - Windows.Theme.FromTheme(cboTheme.SelectedItem) + + ThemeManager.ActiveTheme = cboTheme.SelectedItem + ThemePropertyGrid.SelectedObject = ThemeManager.ActiveTheme ThemePropertyGrid.Refresh() End Sub - Private Sub ThemePropertyGrid_Enter(ByVal sender As Object, ByVal e As EventArgs) Handles ThemePropertyGrid.Enter - If cboTheme.SelectedItem Is _defaultTheme Then - Dim newTheme As New Config.Theme - btnThemeSave.Enabled = True - btnThemeDelete.Enabled = True - cboTheme.Text = "" - Windows.Theme.FromTheme(newTheme) - ThemePropertyGrid.Refresh() - End If - End Sub + Private Sub btnThemeNew_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnThemeNew.Click + Dim newTheme As ThemeInfo = ThemeManager.ActiveTheme.Clone() + newTheme.Name = "Unnamed Theme" - Private Sub btnThemeSave_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnThemeSave.Click - If cboTheme.SelectedItem Is _defaultTheme Then Return - If cboTheme.Text = "" Then - cboTheme.Focus() - Return - End If + _themeList.Add(newTheme) - Dim found As Boolean = False - For Each theme As Config.Theme In _themes - If Not theme.Name = cboTheme.Text Then Continue For + cboTheme.SelectedItem = newTheme + cboTheme_SelectionChangeCommitted(Me, New EventArgs()) - theme.FromTheme(Windows.Theme) - found = True - Exit For - Next - - If Not found Then - Dim newTheme As New Config.Theme - newTheme.FromTheme(Windows.Theme) - newTheme.Name = cboTheme.Text - _themes.Add(newTheme) - cboTheme.Items.Add(newTheme) - End If - - Config.ThemeSerializer.SaveToXmlFile(_themes, Path.Combine(App.Info.Settings.SettingsPath, App.Info.Settings.ThemesFileName)) + cboTheme.Focus() End Sub Private Sub btnThemeDelete_Click(sender As System.Object, e As EventArgs) Handles btnThemeDelete.Click - Dim theme As Config.Theme = cboTheme.SelectedItem - If theme Is Nothing OrElse Not cboTheme.Text = theme.Name Then Return - cboTheme.Focus() - cboTheme.Items.Remove(theme) - cboTheme.SelectedItem = cboTheme.Items.Item(0) + Dim theme As ThemeInfo = cboTheme.SelectedItem + If theme Is Nothing Then Return + + _themeList.Remove(theme) + + cboTheme.SelectedItem = ThemeManager.DefaultTheme cboTheme_SelectionChangeCommitted(Me, New EventArgs()) - _themes.Remove(theme) End Sub #End Region End Class diff --git a/mRemoteV1/Themes/ThemeInfo.vb b/mRemoteV1/Themes/ThemeInfo.vb new file mode 100644 index 00000000..66708f77 --- /dev/null +++ b/mRemoteV1/Themes/ThemeInfo.vb @@ -0,0 +1,308 @@ +Imports System.ComponentModel +Imports mRemoteNG.My + +Namespace Themes + Public Class ThemeInfo + Implements ICloneable, INotifyPropertyChanged +#Region "Public Methods" + Public Sub New(Optional ByVal themeName As String = Nothing) + If themeName IsNot Nothing Then Name = themeName + End Sub + + Public Function Clone() As Object Implements ICloneable.Clone + Return MemberwiseClone() + End Function + + Public Overrides Function ToString() As String + Return Name + End Function +#End Region + +#Region "Events" + Public Event PropertyChanged(sender As Object, e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged + Protected Sub NotifyPropertyChanged(ByVal propertyName As String) + RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName)) + End Sub +#End Region + +#Region "Properties" + Private _name As String = "Unnamed Theme" + _ + Public Property Name As String + Get + Return _name + End Get + Set(value As String) + If _name = value Then Return + _name = value + NotifyPropertyChanged("Name") + End Set + End Property + +#Region "General" + Private _windowBackgroundColor As Color = SystemColors.AppWorkspace + _ + Public Property WindowBackgroundColor() As Color + Get + Return (_windowBackgroundColor) + End Get + Set(value As Color) + If _windowBackgroundColor = value Then Return + _windowBackgroundColor = value + NotifyPropertyChanged("WindowBackgroundColor") + End Set + End Property + + Private _menuBackgroundColor As Color = SystemColors.Control + + Public Property MenuBackgroundColor() As Color + Get + Return _menuBackgroundColor + End Get + Set(value As Color) + If _menuBackgroundColor = value Then Return + _menuBackgroundColor = value + NotifyPropertyChanged("MenuBackgroundColor") + End Set + End Property + + Private _menuTextColor As Color = SystemColors.ControlText + + Public Property MenuTextColor() As Color + Get + Return _menuTextColor + End Get + Set(value As Color) + If _menuTextColor = value Then Return + _menuTextColor = value + NotifyPropertyChanged("MenuTextColor") + End Set + End Property + + Private _toolbarBackgroundColor As Color = SystemColors.Control + _ + Public Property ToolbarBackgroundColor() As Color + Get + Return _toolbarBackgroundColor + End Get + Set(value As Color) + If _toolbarBackgroundColor = value Then Return + _toolbarBackgroundColor = value + NotifyPropertyChanged("ToolbarBackgroundColor") + End Set + End Property + + Private _toolbarTextColor As Color = SystemColors.ControlText + _ + Public Property ToolbarTextColor() As Color + Get + Return _toolbarTextColor + End Get + Set(value As Color) + If _toolbarTextColor = value Then Return + _toolbarTextColor = value + NotifyPropertyChanged("ToolbarTextColor") + End Set + End Property +#End Region + +#Region "Connections Panel" + Private _connectionsPanelBackgroundColor As Color = SystemColors.Window + _ + Public Property ConnectionsPanelBackgroundColor() As Color + Get + Return _connectionsPanelBackgroundColor + End Get + Set(value As Color) + If _connectionsPanelBackgroundColor = value Or value = Color.Transparent Then Return + _connectionsPanelBackgroundColor = value + NotifyPropertyChanged("ConnectionsPanelBackgroundColor") + End Set + End Property + + Private _connectionsPanelTextColor As Color = SystemColors.WindowText + + Public Property ConnectionsPanelTextColor() As Color + Get + Return _connectionsPanelTextColor + End Get + Set(value As Color) + If _connectionsPanelTextColor = value Then Return + _connectionsPanelTextColor = value + NotifyPropertyChanged("ConnectionsPanelTextColor") + End Set + End Property + + Private _connectionsPanelTreeLineColor As Color = Color.Black + + Public Property ConnectionsPanelTreeLineColor() As Color + Get + Return _connectionsPanelTreeLineColor + End Get + Set(value As Color) + If _connectionsPanelTreeLineColor = value Then Return + _connectionsPanelTreeLineColor = value + NotifyPropertyChanged("ConnectionsPanelTreeLineColor") + End Set + End Property + + Private _searchBoxBackgroundColor As Color = SystemColors.Window + _ + Public Property SearchBoxBackgroundColor() As Color + Get + Return _searchBoxBackgroundColor + End Get + Set(value As Color) + If _searchBoxBackgroundColor = value Or value = Color.Transparent Then Return + _searchBoxBackgroundColor = value + NotifyPropertyChanged("SearchBoxBackgroundColor") + End Set + End Property + + Private _searchBoxTextPromptColor As Color = SystemColors.GrayText + _ + Public Property SearchBoxTextPromptColor() As Color + Get + Return _searchBoxTextPromptColor + End Get + Set(value As Color) + If _searchBoxTextPromptColor = value Then Return + _searchBoxTextPromptColor = value + NotifyPropertyChanged("SearchBoxTextPromptColor") + End Set + End Property + + Private _searchBoxTextColor As Color = SystemColors.WindowText + _ + Public Property SearchBoxTextColor() As Color + Get + Return _searchBoxTextColor + End Get + Set(value As Color) + If _searchBoxTextColor = value Then Return + _searchBoxTextColor = value + NotifyPropertyChanged("SearchBoxTextColor") + End Set + End Property +#End Region + +#Region "Config Panel" + Private _configPanelBackgroundColor As Color = SystemColors.Window + _ + Public Property ConfigPanelBackgroundColor() As Color + Get + Return _configPanelBackgroundColor + End Get + Set(value As Color) + If _configPanelBackgroundColor = value Or value = Color.Transparent Then Return + _configPanelBackgroundColor = value + NotifyPropertyChanged("ConfigPanelBackgroundColor") + End Set + End Property + + Private _configPanelTextColor As Color = SystemColors.WindowText + _ + Public Property ConfigPanelTextColor() As Color + Get + Return _configPanelTextColor + End Get + Set(value As Color) + If _configPanelTextColor = value Then Return + _configPanelTextColor = value + NotifyPropertyChanged("ConfigPanelTextColor") + End Set + End Property + + Private _configPanelCategoryTextColor As Color = SystemColors.ControlText + _ + Public Property ConfigPanelCategoryTextColor() As Color + Get + Return _configPanelCategoryTextColor + End Get + Set(value As Color) + If _configPanelCategoryTextColor = value Then Return + _configPanelCategoryTextColor = value + NotifyPropertyChanged("ConfigPanelCategoryTextColor") + End Set + End Property + + Private _configPanelHelpBackgroundColor As Color = SystemColors.Control + _ + Public Property ConfigPanelHelpBackgroundColor() As Color + Get + Return _configPanelHelpBackgroundColor + End Get + Set(value As Color) + If _configPanelHelpBackgroundColor = value Or value = Color.Transparent Then Return + _configPanelHelpBackgroundColor = value + NotifyPropertyChanged("ConfigPanelHelpBackgroundColor") + End Set + End Property + + Private _configPanelHelpTextColor As Color = SystemColors.ControlText + _ + Public Property ConfigPanelHelpTextColor() As Color + Get + Return _configPanelHelpTextColor + End Get + Set(value As Color) + If _configPanelHelpTextColor = value Then Return + _configPanelHelpTextColor = value + NotifyPropertyChanged("ConfigPanelHelpTextColor") + End Set + End Property + + Private _configPanelGridLineColor As Color = SystemColors.InactiveBorder + _ + Public Property ConfigPanelGridLineColor() As Color + Get + Return _configPanelGridLineColor + End Get + Set(value As Color) + If _configPanelGridLineColor = value Then Return + _configPanelGridLineColor = value + NotifyPropertyChanged("ConfigPanelGridLineColor") + End Set + End Property +#End Region +#End Region + End Class +End Namespace diff --git a/mRemoteV1/Themes/ThemeManager.vb b/mRemoteV1/Themes/ThemeManager.vb new file mode 100644 index 00000000..a694d474 --- /dev/null +++ b/mRemoteV1/Themes/ThemeManager.vb @@ -0,0 +1,69 @@ +Imports System.IO +Imports System.ComponentModel + +Namespace Themes + Public Class ThemeManager +#Region "Public Methods" + Public Shared Function LoadThemes() As List(Of ThemeInfo) + Dim themes As New List(Of ThemeInfo) + themes.Add(DefaultTheme) + themes.AddRange(ThemeSerializer.LoadFromXmlFile(Path.Combine(App.Info.Settings.SettingsPath, App.Info.Settings.ThemesFileName))) + Return themes + End Function + + Public Shared Sub SaveThemes(ByVal themes As List(Of ThemeInfo)) + themes.Remove(DefaultTheme) + ThemeSerializer.SaveToXmlFile(themes, Path.Combine(App.Info.Settings.SettingsPath, App.Info.Settings.ThemesFileName)) + End Sub + + Public Shared Sub SaveThemes(ByVal themes As ThemeInfo()) + SaveThemes(New List(Of ThemeInfo)(themes)) + End Sub + + Public Shared Sub SaveThemes(ByVal themes As BindingList(Of ThemeInfo)) + Dim themesArray(themes.Count - 1) As ThemeInfo + themes.CopyTo(themesArray, 0) + SaveThemes(themesArray) + End Sub +#End Region + +#Region "Events" + Public Shared Event ThemeChanged() + Protected Shared Sub NotifyThemeChanged(sender As Object, e As System.ComponentModel.PropertyChangedEventArgs) + If e.PropertyName = "Name" Then Return + RaiseEvent ThemeChanged() + End Sub +#End Region + +#Region "Properties" + ' ReSharper disable InconsistentNaming + Private Shared ReadOnly _defaultTheme As New ThemeInfo("(Default Theme)") + ' ReSharper restore InconsistentNaming + Public Shared ReadOnly Property DefaultTheme As ThemeInfo + Get + Return _defaultTheme + End Get + End Property + + Private Shared _activeTheme As ThemeInfo + Private Shared _activeThemeHandlerSet As Boolean = False + Public Shared Property ActiveTheme As ThemeInfo + Get + Return _activeTheme + End Get + Set(value As ThemeInfo) + If _activeTheme Is Nothing OrElse Not _activeTheme.Equals(value) Then + If _activeThemeHandlerSet Then RemoveHandler _activeTheme.PropertyChanged, AddressOf NotifyThemeChanged + + _activeTheme = value + + AddHandler _activeTheme.PropertyChanged, AddressOf NotifyThemeChanged + _activeThemeHandlerSet = True + + NotifyThemeChanged(_activeTheme, New PropertyChangedEventArgs("")) + End If + End Set + End Property +#End Region + End Class +End Namespace diff --git a/mRemoteV1/Config/ThemeSerializer.vb b/mRemoteV1/Themes/ThemeSerializer.vb similarity index 80% rename from mRemoteV1/Config/ThemeSerializer.vb rename to mRemoteV1/Themes/ThemeSerializer.vb index b4c067f1..97f1a4a4 100644 --- a/mRemoteV1/Config/ThemeSerializer.vb +++ b/mRemoteV1/Themes/ThemeSerializer.vb @@ -2,15 +2,15 @@ Imports System.Xml Imports System.Reflection -Namespace Config +Namespace Themes Public Class ThemeSerializer - Public Shared Sub SaveToXmlFile(theme As Theme, filename As String) - Dim themeList As New List(Of Theme) - themeList.Add(theme) + Public Shared Sub SaveToXmlFile(themeInfo As ThemeInfo, filename As String) + Dim themeList As New List(Of ThemeInfo) + themeList.Add(ThemeInfo) SaveToXmlFile(themeList, filename) End Sub - Public Shared Sub SaveToXmlFile(themes As List(Of Theme), filename As String) + Public Shared Sub SaveToXmlFile(themes As List(Of ThemeInfo), filename As String) Dim tempFileName As String = Path.GetTempFileName() Dim xmlTextWriter As New XmlTextWriter(tempFileName, System.Text.Encoding.UTF8) @@ -27,16 +27,16 @@ Namespace Config xmlTextWriter.WriteElementString("FileTypeVersion", "1.0") xmlTextWriter.WriteEndElement() ' FileInfo - Dim themeType As Type = (New Theme).GetType() + Dim themeType As Type = (New ThemeInfo).GetType() Dim colorType As Type = (New Color).GetType() Dim color As Color - For Each theme As Theme In themes + For Each themeInfo As ThemeInfo In themes xmlTextWriter.WriteStartElement("Theme") - xmlTextWriter.WriteAttributeString("Name", theme.Name) + xmlTextWriter.WriteAttributeString("Name", themeInfo.Name) For Each propertyInfo As PropertyInfo In themeType.GetProperties() If Not propertyInfo.PropertyType Is colorType Then Continue For - color = propertyInfo.GetValue(theme, Nothing) + color = propertyInfo.GetValue(themeInfo, Nothing) xmlTextWriter.WriteStartElement("Color") xmlTextWriter.WriteAttributeString("Name", propertyInfo.Name) xmlTextWriter.WriteAttributeString("Value", color.Name) @@ -54,7 +54,7 @@ Namespace Config File.Move(tempFileName, filename) End Sub - Public Shared Function LoadFromXmlFile(filename As String) As List(Of Theme) + Public Shared Function LoadFromXmlFile(filename As String) As List(Of ThemeInfo) Dim xmlDocument As New XmlDocument() xmlDocument.Load(filename) @@ -76,24 +76,24 @@ Namespace Config End If Dim themeNodes As XmlNodeList = xmlDocument.SelectNodes("/mRemoteNG/Theme") - Dim themes As New List(Of Theme) - Dim theme As Theme - Dim themeType As Type = (New Theme).GetType() + Dim themes As New List(Of ThemeInfo) + Dim themeInfo As ThemeInfo + Dim themeType As Type = (New ThemeInfo).GetType() Dim colorType As Type = (New Color).GetType() Dim colorName As String Dim colorValue As String Dim propertyInfo As PropertyInfo For Each themeNode As XmlNode In themeNodes - theme = New Theme - theme.Name = themeNode.Attributes("Name").Value + themeInfo = New ThemeInfo + themeInfo.Name = themeNode.Attributes("Name").Value For Each colorNode As XmlNode In themeNode.SelectNodes("./Color") colorName = colorNode.Attributes("Name").Value colorValue = colorNode.Attributes("Value").Value propertyInfo = themeType.GetProperty(colorName) If propertyInfo Is Nothing OrElse Not propertyInfo.PropertyType Is colorType Then Continue For - propertyInfo.SetValue(theme, Color.FromName(colorValue), Nothing) + propertyInfo.SetValue(themeInfo, Color.FromName(colorValue), Nothing) Next - themes.Add(theme) + themes.Add(themeInfo) Next Return themes diff --git a/mRemoteV1/UI/UI.Window.Config.vb b/mRemoteV1/UI/UI.Window.Config.vb index d7351304..42307db9 100644 --- a/mRemoteV1/UI/UI.Window.Config.vb +++ b/mRemoteV1/UI/UI.Window.Config.vb @@ -489,15 +489,15 @@ Namespace UI End Sub Private Sub ApplyTheme() - With Windows.Theme - pGrid.BackColor = .ToolbarBackground - pGrid.ForeColor = .ToolbarText - pGrid.ViewBackColor = .ConfigPanelBackground - pGrid.ViewForeColor = .ConfigPanelText - pGrid.LineColor = .ConfigPanelGridLines - pGrid.HelpBackColor = .ConfigPanelHelpBackground - pGrid.HelpForeColor = .ConfigPanelHelpText - pGrid.CategoryForeColor = .ConfigPanelCategoryText + With Themes.ThemeManager.ActiveTheme + pGrid.BackColor = .ToolbarBackgroundColor + pGrid.ForeColor = .ToolbarTextColor + pGrid.ViewBackColor = .ConfigPanelBackgroundColor + pGrid.ViewForeColor = .ConfigPanelTextColor + pGrid.LineColor = .ConfigPanelGridLineColor + pGrid.HelpBackColor = .ConfigPanelHelpBackgroundColor + pGrid.HelpForeColor = .ConfigPanelHelpTextColor + pGrid.CategoryForeColor = .ConfigPanelCategoryTextColor End With End Sub @@ -554,7 +554,7 @@ Namespace UI Private Sub Config_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load ApplyLanguage() - AddHandler Windows.Theme.ThemeChanged, AddressOf ApplyTheme + AddHandler Themes.ThemeManager.ThemeChanged, AddressOf ApplyTheme ApplyTheme() AddToolStripItems() diff --git a/mRemoteV1/UI/UI.Window.Tree.vb b/mRemoteV1/UI/UI.Window.Tree.vb index 24e305e9..3a93668a 100644 --- a/mRemoteV1/UI/UI.Window.Tree.vb +++ b/mRemoteV1/UI/UI.Window.Tree.vb @@ -466,7 +466,7 @@ Namespace UI Private Sub Tree_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load ApplyLanguage() - AddHandler Windows.Theme.ThemeChanged, AddressOf ApplyTheme + AddHandler Themes.ThemeManager.ThemeChanged, AddressOf ApplyTheme ApplyTheme() txtSearch.Multiline = True @@ -512,15 +512,15 @@ Namespace UI End Sub Public Sub ApplyTheme() - With Windows.Theme - msMain.BackColor = .ToolbarBackground - msMain.ForeColor = .ToolbarText - tvConnections.BackColor = .ConnectionsPanelBackground - tvConnections.ForeColor = .ConnectionsPanelText - tvConnections.LineColor = .ConnectionsPanelTreeLines - BackColor = .ToolbarBackground - txtSearch.BackColor = .SearchBoxBackground - txtSearch.ForeColor = .SearchBoxTextPrompt + With Themes.ThemeManager.ActiveTheme + msMain.BackColor = .ToolbarBackgroundColor + msMain.ForeColor = .ToolbarTextColor + tvConnections.BackColor = .ConnectionsPanelBackgroundColor + tvConnections.ForeColor = .ConnectionsPanelTextColor + tvConnections.LineColor = .ConnectionsPanelTreeLineColor + BackColor = .ToolbarBackgroundColor + txtSearch.BackColor = .SearchBoxBackgroundColor + txtSearch.ForeColor = .SearchBoxTextPromptColor End With End Sub #End Region @@ -1227,7 +1227,7 @@ Namespace UI #Region "Search" Private Sub txtSearch_GotFocus(ByVal sender As Object, ByVal e As EventArgs) Handles txtSearch.GotFocus - txtSearch.ForeColor = Windows.Theme.SearchBoxText + txtSearch.ForeColor = Themes.ThemeManager.ActiveTheme.SearchBoxTextColor If txtSearch.Text = Language.strSearchPrompt Then txtSearch.Text = "" End If @@ -1235,7 +1235,7 @@ Namespace UI Private Sub txtSearch_LostFocus(ByVal sender As Object, ByVal e As EventArgs) Handles txtSearch.LostFocus If txtSearch.Text = "" Then - txtSearch.ForeColor = Windows.Theme.SearchBoxTextPrompt + txtSearch.ForeColor = Themes.ThemeManager.ActiveTheme.SearchBoxTextPromptColor txtSearch.Text = Language.strSearchPrompt End If End Sub diff --git a/mRemoteV1/mRemoteV1.vbproj b/mRemoteV1/mRemoteV1.vbproj index 9915a9bd..b68c4f63 100644 --- a/mRemoteV1/mRemoteV1.vbproj +++ b/mRemoteV1/mRemoteV1.vbproj @@ -187,7 +187,8 @@ - + + @@ -216,7 +217,7 @@ - +