From 39bd4b8d6661870f8b765103bea8482e9b2cf044 Mon Sep 17 00:00:00 2001 From: molsonkiko <46202915+molsonkiko@users.noreply.github.com> Date: Fri, 28 Apr 2023 12:50:45 -0700 Subject: [PATCH 1/2] apply dark mode to all forms automatically Based on https://github.com/kbilsted/NotepadPlusPlusPluginPack.Net/pull/104 Rdipardo did all the hard work here, this is just a refinement. This makes it easy for plugin makers to apply dark mode to all forms. Rather than having to individually select themes to apply for each control, sensible defaults are applied based on each control's type. This PR also allows the color changes to propagate recursively to a form's child forms, if it has any. --- Demo Plugin/NppManagedPluginDemo/Demo.cs | 111 +++++++- .../Forms/DarkModeTestForm.Designer.cs | 236 ++++++++++++++++++ .../Forms/DarkModeTestForm.cs | 28 +++ .../Forms/DarkModeTestForm.resx | 177 +++++++++++++ .../NppManagedPluginDemo/Forms/frmGoToLine.cs | 17 ++ .../Forms/frmGoToLine.designer.cs | 132 +++++----- .../Forms/frmGoToLine.resx | 4 +- .../$projectname$.csproj | 1 + .../PluginInfrastructure/DarkMode.cs | 56 +++++ .../PluginInfrastructure/Docking_h.cs | 1 + .../PluginInfrastructure/Msgs_h.cs | 23 ++ .../PluginInfrastructure/NotepadPPGateway.cs | 4 +- 12 files changed, 728 insertions(+), 62 deletions(-) create mode 100644 Demo Plugin/NppManagedPluginDemo/Forms/DarkModeTestForm.Designer.cs create mode 100644 Demo Plugin/NppManagedPluginDemo/Forms/DarkModeTestForm.cs create mode 100644 Demo Plugin/NppManagedPluginDemo/Forms/DarkModeTestForm.resx create mode 100644 Visual Studio Project Template C#/PluginInfrastructure/DarkMode.cs diff --git a/Demo Plugin/NppManagedPluginDemo/Demo.cs b/Demo Plugin/NppManagedPluginDemo/Demo.cs index 382d0fe..c975eb4 100644 --- a/Demo Plugin/NppManagedPluginDemo/Demo.cs +++ b/Demo Plugin/NppManagedPluginDemo/Demo.cs @@ -2,7 +2,9 @@ using System; using System.IO; using System.Text; +using System.Collections.Generic; using System.Drawing; +using System.Reflection; using System.Threading; using System.Windows.Forms; using System.Drawing.Imaging; @@ -38,7 +40,13 @@ public static void OnNotification(ScNotification notification) { if (notification.Header.Code == (uint)SciMsg.SCN_CHARADDED) { - Kbg.Demo.Namespace.Main.doInsertHtmlCloseTag((char)notification.Character); + Demo.Namespace.Main.doInsertHtmlCloseTag((char)notification.Character); + } + // dark mode (de-)activated + if (notification.Header.Code == (uint)NppMsg.NPPN_DARKMODECHANGED) + { + INotepadPPGateway notepad = new NotepadPPGateway(); + Demo.Namespace.Main.ToggleDarkMode(Demo.Namespace.Main.frmGoToLine, notepad.IsDarkModeEnabled()); } } @@ -57,7 +65,7 @@ class Main static string keyName = "doCloseTag"; static bool doCloseTag = false; static string sessionFilePath = @"C:\text.session"; - static frmGoToLine frmGoToLine = null; + static internal frmGoToLine frmGoToLine = null; static internal int idFrmGotToLine = -1; // toolbar icons @@ -179,6 +187,104 @@ static internal void PluginCleanUp() { Win32.WritePrivateProfileString(sectionName, keyName, doCloseTag ? "1" : "0", iniFilePath); } + + /// + /// Apply dark mode (or re-apply light mode) to the controls of any form.

+ /// This method currently supports colorizing the following types of controls:

+ /// - Buttons

+ /// - Labels

+ /// - LinkLabels

+ /// - ComboBoxes

+ /// - CheckBoxes

+ /// - ListBoxes

+ /// - TreeViews

+ /// Feel free to add more as needed.

+ /// TODO: Figure out best way to customize border colors of controls. + /// https://stackoverflow.com/questions/1445472/how-to-change-the-form-border-color-c + /// may be a lead. + ///
+ /// a Windows Form + /// is Notepad++ dark mode on? + static internal void ToggleDarkMode(Form form, bool isDark) + { + if (form == null) + return; + IntPtr themePtr = notepad.GetDarkModeColors(); + if (isDark && themePtr == IntPtr.Zero) + return; + var theme = (DarkModeColors)Marshal.PtrToStructure(themePtr, typeof(DarkModeColors)); + foreach (Form childForm in form.OwnedForms) + { + // allow possibility that some forms will have other child forms + // JsonTools does this in a couple of places + ToggleDarkMode(childForm, isDark); + } + if (isDark) + { + form.BackColor = NppDarkMode.BGRToColor(theme.Background); + form.ForeColor = NppDarkMode.BGRToColor(theme.Text); + } + else + { + form.ResetForeColor(); + form.ResetBackColor(); + } + foreach (Control ctrl in form.Controls) + { + if (isDark) + { + // this doesn't actually make disabled controls have different colors + // windows forms don't make it easy for the user to choose the + // color of a disabled control. See https://stackoverflow.com/questions/136129/windows-forms-how-do-you-change-the-font-color-for-a-disabled-label + var textTheme = ctrl.Enabled ? theme.Text : theme.DisabledText; + if (ctrl is Button btn) + { + btn.BackColor = NppDarkMode.BGRToColor(theme.SofterBackground); + btn.ForeColor = NppDarkMode.BGRToColor(textTheme); + } + else if (ctrl is LinkLabel llbl) + { + llbl.BackColor = NppDarkMode.BGRToColor(theme.ErrorBackground); + llbl.ForeColor = NppDarkMode.BGRToColor(theme.DarkerText); + llbl.LinkColor = NppDarkMode.BGRToColor(theme.LinkText); + llbl.ActiveLinkColor = NppDarkMode.BGRToColor(theme.Text); + llbl.VisitedLinkColor = NppDarkMode.BGRToColor(theme.DarkerText); + } + // other common text-based controls + else if (ctrl is TextBox + || ctrl is Label + || ctrl is ListBox + || ctrl is ComboBox) + { + ctrl.BackColor = NppDarkMode.BGRToColor(theme.PureBackground); + ctrl.ForeColor = NppDarkMode.BGRToColor(textTheme); + } + else if (ctrl is TreeView tv) + { + tv.BackColor = NppDarkMode.BGRToColor(theme.HotBackground); + tv.ForeColor = NppDarkMode.BGRToColor(textTheme); + } + else + { + // other controls I haven't thought of yet + ctrl.BackColor = NppDarkMode.BGRToColor(theme.SofterBackground); + ctrl.ForeColor = NppDarkMode.BGRToColor(textTheme); + } + } + else // normal light mode + { + ctrl.ResetForeColor(); + ctrl.ResetBackColor(); + if (ctrl is LinkLabel llbl) + { + llbl.LinkColor = Color.Blue; + llbl.ActiveLinkColor = Color.Red; + llbl.VisitedLinkColor = Color.Purple; + } + } + } + Marshal.FreeHGlobal(themePtr); + } #endregion #region " Menu functions " @@ -443,6 +549,7 @@ static void DockableDlgDemo() Win32.SendMessage(PluginBase.nppData._nppHandle, (uint) NppMsg.NPPM_SETMENUITEMCHECK, PluginBase._funcItems.Items[idFrmGotToLine]._cmdID, 0); } } + ToggleDarkMode(frmGoToLine, notepad.IsDarkModeEnabled()); frmGoToLine.textBox1.Focus(); } diff --git a/Demo Plugin/NppManagedPluginDemo/Forms/DarkModeTestForm.Designer.cs b/Demo Plugin/NppManagedPluginDemo/Forms/DarkModeTestForm.Designer.cs new file mode 100644 index 0000000..e223178 --- /dev/null +++ b/Demo Plugin/NppManagedPluginDemo/Forms/DarkModeTestForm.Designer.cs @@ -0,0 +1,236 @@ +namespace Kbg.Demo.Namespace +{ + partial class DarkModeTestForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.Windows.Forms.TreeNode treeNode8 = new System.Windows.Forms.TreeNode("Node6"); + System.Windows.Forms.TreeNode treeNode9 = new System.Windows.Forms.TreeNode("Node4", new System.Windows.Forms.TreeNode[] { + treeNode8}); + System.Windows.Forms.TreeNode treeNode10 = new System.Windows.Forms.TreeNode("Node5", 2, 2); + System.Windows.Forms.TreeNode treeNode11 = new System.Windows.Forms.TreeNode("Node1", 1, 1, new System.Windows.Forms.TreeNode[] { + treeNode9, + treeNode10}); + System.Windows.Forms.TreeNode treeNode12 = new System.Windows.Forms.TreeNode("Node3", 2, 2); + System.Windows.Forms.TreeNode treeNode13 = new System.Windows.Forms.TreeNode("Node2", 1, 1, new System.Windows.Forms.TreeNode[] { + treeNode12}); + System.Windows.Forms.TreeNode treeNode14 = new System.Windows.Forms.TreeNode("TreeView example", new System.Windows.Forms.TreeNode[] { + treeNode11, + treeNode13}); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DarkModeTestForm)); + this.button1 = new System.Windows.Forms.Button(); + this.treeView1 = new System.Windows.Forms.TreeView(); + this.listBox1 = new System.Windows.Forms.ListBox(); + this.Title = new System.Windows.Forms.Label(); + this.comboBox1 = new System.Windows.Forms.ComboBox(); + this.linkLabel1 = new System.Windows.Forms.LinkLabel(); + this.label1 = new System.Windows.Forms.Label(); + this.checkBox1 = new System.Windows.Forms.CheckBox(); + this.imageList1 = new System.Windows.Forms.ImageList(this.components); + this.textBox1 = new System.Windows.Forms.TextBox(); + this.textBox2 = new System.Windows.Forms.TextBox(); + this.SuspendLayout(); + // + // button1 + // + this.button1.Location = new System.Drawing.Point(217, 301); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(75, 23); + this.button1.TabIndex = 0; + this.button1.Text = "button1"; + this.button1.UseVisualStyleBackColor = true; + // + // treeView1 + // + this.treeView1.ImageIndex = 0; + this.treeView1.ImageList = this.imageList1; + this.treeView1.Location = new System.Drawing.Point(12, 100); + this.treeView1.Name = "treeView1"; + treeNode8.Name = "Node6"; + treeNode8.Text = "Node6"; + treeNode9.Name = "Node4"; + treeNode9.Text = "Node4"; + treeNode10.ImageIndex = 2; + treeNode10.Name = "Node5"; + treeNode10.SelectedImageIndex = 2; + treeNode10.Text = "Node5"; + treeNode11.ImageIndex = 1; + treeNode11.Name = "Node1"; + treeNode11.SelectedImageIndex = 1; + treeNode11.Text = "Node1"; + treeNode12.ImageIndex = 2; + treeNode12.Name = "Node3"; + treeNode12.SelectedImageIndex = 2; + treeNode12.Text = "Node3"; + treeNode13.ImageIndex = 1; + treeNode13.Name = "Node2"; + treeNode13.SelectedImageIndex = 1; + treeNode13.Text = "Node2"; + treeNode14.Name = "TreeViewRoot"; + treeNode14.Text = "TreeView example"; + this.treeView1.Nodes.AddRange(new System.Windows.Forms.TreeNode[] { + treeNode14}); + this.treeView1.SelectedImageIndex = 0; + this.treeView1.Size = new System.Drawing.Size(178, 135); + this.treeView1.TabIndex = 1; + // + // listBox1 + // + this.listBox1.FormattingEnabled = true; + this.listBox1.ItemHeight = 16; + this.listBox1.Items.AddRange(new object[] { + "listBox1", + "this", + "is", + "a", + "listBox"}); + this.listBox1.Location = new System.Drawing.Point(362, 100); + this.listBox1.Name = "listBox1"; + this.listBox1.SelectionMode = System.Windows.Forms.SelectionMode.MultiSimple; + this.listBox1.Size = new System.Drawing.Size(120, 132); + this.listBox1.TabIndex = 2; + // + // Title + // + this.Title.AutoSize = true; + this.Title.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic))), System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.Title.Location = new System.Drawing.Point(112, 33); + this.Title.Name = "Title"; + this.Title.Size = new System.Drawing.Size(323, 18); + this.Title.TabIndex = 3; + this.Title.Text = "Each control in this form should look nice"; + // + // comboBox1 + // + this.comboBox1.FormattingEnabled = true; + this.comboBox1.Items.AddRange(new object[] { + "comboBox1", + "this", + "is", + "a", + "comboBox"}); + this.comboBox1.Location = new System.Drawing.Point(217, 98); + this.comboBox1.Name = "comboBox1"; + this.comboBox1.Size = new System.Drawing.Size(121, 24); + this.comboBox1.TabIndex = 4; + // + // linkLabel1 + // + this.linkLabel1.AutoSize = true; + this.linkLabel1.LinkArea = new System.Windows.Forms.LinkArea(0, 10); + this.linkLabel1.Location = new System.Drawing.Point(376, 275); + this.linkLabel1.Name = "linkLabel1"; + this.linkLabel1.Size = new System.Drawing.Size(145, 49); + this.linkLabel1.TabIndex = 5; + this.linkLabel1.TabStop = true; + this.linkLabel1.Text = "linkLabel1\r\nuses ErrorBackground\r\nand DarkerText"; + this.linkLabel1.UseCompatibleTextRendering = true; + this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.LinkLabel_LinkClicked); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(36, 308); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(105, 16); + this.label1.TabIndex = 6; + this.label1.Text = "A non-bold label"; + // + // checkBox1 + // + this.checkBox1.AutoSize = true; + this.checkBox1.Location = new System.Drawing.Point(179, 265); + this.checkBox1.Name = "checkBox1"; + this.checkBox1.Size = new System.Drawing.Size(173, 20); + this.checkBox1.TabIndex = 7; + this.checkBox1.Text = "checkBox1 looks good?"; + this.checkBox1.UseVisualStyleBackColor = true; + // + // imageList1 + // + this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream"))); + this.imageList1.TransparentColor = System.Drawing.Color.Transparent; + this.imageList1.Images.SetKeyName(0, "star.png"); + this.imageList1.Images.SetKeyName(1, "star_black.ico"); + this.imageList1.Images.SetKeyName(2, "star_white.ico"); + // + // textBox1 + // + this.textBox1.Location = new System.Drawing.Point(217, 190); + this.textBox1.Multiline = true; + this.textBox1.Name = "textBox1"; + this.textBox1.Size = new System.Drawing.Size(121, 23); + this.textBox1.TabIndex = 8; + this.textBox1.Text = "textBox1"; + // + // textBox2 + // + this.textBox2.Enabled = false; + this.textBox2.Location = new System.Drawing.Point(217, 144); + this.textBox2.Name = "textBox2"; + this.textBox2.Size = new System.Drawing.Size(121, 22); + this.textBox2.TabIndex = 9; + this.textBox2.Text = "disabled textbox"; + // + // DarkModeTestForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(577, 358); + this.Controls.Add(this.textBox2); + this.Controls.Add(this.textBox1); + this.Controls.Add(this.checkBox1); + this.Controls.Add(this.label1); + this.Controls.Add(this.linkLabel1); + this.Controls.Add(this.comboBox1); + this.Controls.Add(this.Title); + this.Controls.Add(this.listBox1); + this.Controls.Add(this.treeView1); + this.Controls.Add(this.button1); + this.Name = "DarkModeTestForm"; + this.Text = "DarkModeTestForm"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button button1; + private System.Windows.Forms.TreeView treeView1; + private System.Windows.Forms.ListBox listBox1; + private System.Windows.Forms.Label Title; + private System.Windows.Forms.ComboBox comboBox1; + private System.Windows.Forms.LinkLabel linkLabel1; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.CheckBox checkBox1; + private System.Windows.Forms.ImageList imageList1; + private System.Windows.Forms.TextBox textBox1; + private System.Windows.Forms.TextBox textBox2; + } +} \ No newline at end of file diff --git a/Demo Plugin/NppManagedPluginDemo/Forms/DarkModeTestForm.cs b/Demo Plugin/NppManagedPluginDemo/Forms/DarkModeTestForm.cs new file mode 100644 index 0000000..a0aeb39 --- /dev/null +++ b/Demo Plugin/NppManagedPluginDemo/Forms/DarkModeTestForm.cs @@ -0,0 +1,28 @@ +using Kbg.NppPluginNET.PluginInfrastructure; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace Kbg.Demo.Namespace +{ + public partial class DarkModeTestForm : Form + { + public DarkModeTestForm() + { + InitializeComponent(); + var notepad = new NotepadPPGateway(); + Main.ToggleDarkMode(this, notepad.IsDarkModeEnabled()); + comboBox1.SelectedIndex = 0; + } + + private void LinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + linkLabel1.LinkVisited = !linkLabel1.LinkVisited; + } + } +} diff --git a/Demo Plugin/NppManagedPluginDemo/Forms/DarkModeTestForm.resx b/Demo Plugin/NppManagedPluginDemo/Forms/DarkModeTestForm.resx new file mode 100644 index 0000000..811e322 --- /dev/null +++ b/Demo Plugin/NppManagedPluginDemo/Forms/DarkModeTestForm.resx @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADw + CgAAAk1TRnQBSQFMAgEBAwEAAQgBAAEIAQABEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo + AwABQAMAARADAAEBAQABCAYAAQQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA + AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 + AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA + AWYDAAGZAwABzAIAATMDAAIzAgABMwFmAgABMwGZAgABMwHMAgABMwH/AgABZgMAAWYBMwIAAmYCAAFm + AZkCAAFmAcwCAAFmAf8CAAGZAwABmQEzAgABmQFmAgACmQIAAZkBzAIAAZkB/wIAAcwDAAHMATMCAAHM + AWYCAAHMAZkCAALMAgABzAH/AgAB/wFmAgAB/wGZAgAB/wHMAQABMwH/AgAB/wEAATMBAAEzAQABZgEA + ATMBAAGZAQABMwEAAcwBAAEzAQAB/wEAAf8BMwIAAzMBAAIzAWYBAAIzAZkBAAIzAcwBAAIzAf8BAAEz + AWYCAAEzAWYBMwEAATMCZgEAATMBZgGZAQABMwFmAcwBAAEzAWYB/wEAATMBmQIAATMBmQEzAQABMwGZ + AWYBAAEzApkBAAEzAZkBzAEAATMBmQH/AQABMwHMAgABMwHMATMBAAEzAcwBZgEAATMBzAGZAQABMwLM + AQABMwHMAf8BAAEzAf8BMwEAATMB/wFmAQABMwH/AZkBAAEzAf8BzAEAATMC/wEAAWYDAAFmAQABMwEA + AWYBAAFmAQABZgEAAZkBAAFmAQABzAEAAWYBAAH/AQABZgEzAgABZgIzAQABZgEzAWYBAAFmATMBmQEA + AWYBMwHMAQABZgEzAf8BAAJmAgACZgEzAQADZgEAAmYBmQEAAmYBzAEAAWYBmQIAAWYBmQEzAQABZgGZ + AWYBAAFmApkBAAFmAZkBzAEAAWYBmQH/AQABZgHMAgABZgHMATMBAAFmAcwBmQEAAWYCzAEAAWYBzAH/ + AQABZgH/AgABZgH/ATMBAAFmAf8BmQEAAWYB/wHMAQABzAEAAf8BAAH/AQABzAEAApkCAAGZATMBmQEA + AZkBAAGZAQABmQEAAcwBAAGZAwABmQIzAQABmQEAAWYBAAGZATMBzAEAAZkBAAH/AQABmQFmAgABmQFm + ATMBAAGZATMBZgEAAZkBZgGZAQABmQFmAcwBAAGZATMB/wEAApkBMwEAApkBZgEAA5kBAAKZAcwBAAKZ + Af8BAAGZAcwCAAGZAcwBMwEAAWYBzAFmAQABmQHMAZkBAAGZAswBAAGZAcwB/wEAAZkB/wIAAZkB/wEz + AQABmQHMAWYBAAGZAf8BmQEAAZkB/wHMAQABmQL/AQABzAMAAZkBAAEzAQABzAEAAWYBAAHMAQABmQEA + AcwBAAHMAQABmQEzAgABzAIzAQABzAEzAWYBAAHMATMBmQEAAcwBMwHMAQABzAEzAf8BAAHMAWYCAAHM + AWYBMwEAAZkCZgEAAcwBZgGZAQABzAFmAcwBAAGZAWYB/wEAAcwBmQIAAcwBmQEzAQABzAGZAWYBAAHM + ApkBAAHMAZkBzAEAAcwBmQH/AQACzAIAAswBMwEAAswBZgEAAswBmQEAA8wBAALMAf8BAAHMAf8CAAHM + Af8BMwEAAZkB/wFmAQABzAH/AZkBAAHMAf8BzAEAAcwC/wEAAcwBAAEzAQAB/wEAAWYBAAH/AQABmQEA + AcwBMwIAAf8CMwEAAf8BMwFmAQAB/wEzAZkBAAH/ATMBzAEAAf8BMwH/AQAB/wFmAgAB/wFmATMBAAHM + AmYBAAH/AWYBmQEAAf8BZgHMAQABzAFmAf8BAAH/AZkCAAH/AZkBMwEAAf8BmQFmAQAB/wKZAQAB/wGZ + AcwBAAH/AZkB/wEAAf8BzAIAAf8BzAEzAQAB/wHMAWYBAAH/AcwBmQEAAf8CzAEAAf8BzAH/AQAC/wEz + AQABzAH/AWYBAAL/AZkBAAL/AcwBAAJmAf8BAAFmAf8BZgEAAWYC/wEAAf8CZgEAAf8BZgH/AQAC/wFm + AQABIQEAAaUBAANfAQADdwEAA4YBAAOWAQADywEAA7IBAAPXAQAD3QEAA+MBAAPqAQAD8QEAA/gBAAHw + AfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD/wUAAfQBkwFMAUYBJQFM + AZMB9AgAAfQBDgUAAewIAAH0BvEB8hcAAZMBRgclAXQGAAEVAQAB9AUAAe0BAAH0BQAC8QH/BQAB8gHx + AfQTAAH/AW8BRgIlASQEJQEkASUBTAH/AwABDwHrCAAB/wEAAfQDAALyCAAB/wHxAfQSAAGTAUYCJQGU + AUUCJAFGAZkBJAIlAXQCAAGSARQCAAEOAW0CAAH0AQABvAEAAf8DAALyAgAB8QHyAgAB/wHxAfMBAAH/ + AfERAAH0AUwDJQEbAf8BdAGTAf8BGgEkAyUB9AUAARMB8QEAAewBEAEAARACAAHtAewBAAHxAwAB8QH0 + AfEB8gHxAQAB8QIAAvIQAAGTAUYDJQEaBP8BmQEkAyUBdAG8AW0FAAH/AbwBAAEHAfEEAAHzAfIDAAHx + AQAB/wHzAQAB8wH0AwAB8RAAAXQEJQGTBP8BkwEkAyUBTAETAfMDAAFtAf8DAAEOBQAB8gH0AwAB8gH/ + AwAB8QQAAfEQAAFvAyUBbwb/AW8BJAMlAQAB/wIAAeoBbQQAAfQBAAH0AwAB8QH/AgAC8gQAAf8B8QH/ + AgAB8RAAAW8CJQFvCP8BbwIlAUYBDgH/AQABFQHxBwABDgMAAfEB/wEAAfIB9AcAAfEB/wEAAfEQAAF0 + AiUBTAEWAZMBGwL/ARsBkwEWAUwCJQFMAewBBwEAAQcDAAH/AQABDwYAAfIB8wEAAfMD8QH/AQAB8gPx + AgAB8RAAAZMBRgQlAUYC/wFFBSUBdAH/BQAB9AHsBgAB9AEOAf8B8QQAAf8B8gEAAfEEAAH/AfEQAAH0 + AW8FJQIaBSUBRgH0AgAB8wUAAfABvAUAAfQBAAHxAfQEAAHxAvMEAAHxAfQRAAGZAUwEJQJMBCUBRgGT + AgAB/wEAAf8DAAHwARAEAAHrARUCAAH/AfEB/wMAAfMB8gQAAfIB8RIAAf8BdAFMCCUBRgFvAf8DAAHz + AQAB8wcAARQBDwQAAfQB8QH0BwAC8hUAAZkBbwFGBCUBRgFMAZMGAAH/AgABBwL/AfMBbQEAAZIGAAH/ + AvEB8wL/AfQB8gHxAfIXAAH0AZkBdAJvAXQBkwH0CQAB/wHsAQ4BAAETAbwKAAH/AfIC8QHyAfMVAAFC + AU0BPgcAAT4DAAEoAwABQAMAARADAAEBAQABAQUAAYAXAAP/AQAB8AEPAfABDwHwAQ8CAAHgAQcE4wIA + AYABAQHPAfEBzwHxAgABgAEBAZkBiQGZAYkEAAG4ASwBuAEsBAABOgFOAToBTgQAATkB3gE5Ad4EAAEz + AcYBMwHGBAABJwH2AScB8gQAASABhgEgAYYEAAE8AbwBPAG8BAABngE8AZ4BPAIAAYABAQGOAXkBjgF5 + AgABgAEBAccB8wHHAfMCAAHgAQcB4AEHAeABBwIAAfABDwH4AR8B+AEfAgAL + + + \ No newline at end of file diff --git a/Demo Plugin/NppManagedPluginDemo/Forms/frmGoToLine.cs b/Demo Plugin/NppManagedPluginDemo/Forms/frmGoToLine.cs index ba75d36..47d0fc5 100644 --- a/Demo Plugin/NppManagedPluginDemo/Forms/frmGoToLine.cs +++ b/Demo Plugin/NppManagedPluginDemo/Forms/frmGoToLine.cs @@ -8,11 +8,13 @@ namespace Kbg.Demo.Namespace partial class frmGoToLine : Form { private readonly IScintillaGateway editor; + public DarkModeTestForm darkModeTestForm; public frmGoToLine(IScintillaGateway editor) { this.editor = editor; InitializeComponent(); + darkModeTestForm = null; } private void button1_Click(object sender, EventArgs e) @@ -61,5 +63,20 @@ void FrmGoToLineVisibleChanged(object sender, EventArgs e) PluginBase._funcItems.Items[Main.idFrmGotToLine]._cmdID, 0); } } + + private void DarkModeTestFormButton_Click(object sender, EventArgs e) + { + if (darkModeTestForm != null && !darkModeTestForm.IsDisposed) + { + RemoveOwnedForm(darkModeTestForm); + darkModeTestForm.Dispose(); + } + // need to register this as an owned form + // so that Main.ToggleDarkMode can recursively apply dark mode + // to this form. + darkModeTestForm = new DarkModeTestForm(); + darkModeTestForm.Show(); + AddOwnedForm(darkModeTestForm); + } } } diff --git a/Demo Plugin/NppManagedPluginDemo/Forms/frmGoToLine.designer.cs b/Demo Plugin/NppManagedPluginDemo/Forms/frmGoToLine.designer.cs index 0caa768..d9efa89 100644 --- a/Demo Plugin/NppManagedPluginDemo/Forms/frmGoToLine.designer.cs +++ b/Demo Plugin/NppManagedPluginDemo/Forms/frmGoToLine.designer.cs @@ -17,6 +17,8 @@ protected override void Dispose(bool disposing) { components.Dispose(); } + if (darkModeTestForm != null && !darkModeTestForm.IsDisposed) + darkModeTestForm.Dispose(); base.Dispose(disposing); } @@ -28,58 +30,77 @@ protected override void Dispose(bool disposing) /// private void InitializeComponent() { - this.label1 = new System.Windows.Forms.Label(); - this.button1 = new System.Windows.Forms.Button(); - this.textBox1 = new System.Windows.Forms.TextBox(); - this.SuspendLayout(); - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(12, 9); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(55, 13); - this.label1.TabIndex = 0; - this.label1.Text = "Go to line:"; - // - // button1 - // - this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.button1.Location = new System.Drawing.Point(15, 32); - this.button1.Name = "button1"; - this.button1.Size = new System.Drawing.Size(107, 23); - this.button1.TabIndex = 2; - this.button1.Text = "&Go"; - this.button1.UseVisualStyleBackColor = true; - this.button1.Click += new System.EventHandler(this.button1_Click); - this.button1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.frmGoToLine_KeyDown); - // - // textBox1 - // - this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.textBox1.Location = new System.Drawing.Point(73, 6); - this.textBox1.Name = "textBox1"; - this.textBox1.Size = new System.Drawing.Size(49, 20); - this.textBox1.TabIndex = 1; - this.textBox1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.frmGoToLine_KeyDown); - this.textBox1.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.textBox1_KeyPress); - // - // frmGoToLine - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(139, 70); - this.Controls.Add(this.textBox1); - this.Controls.Add(this.button1); - this.Controls.Add(this.label1); - this.Name = "frmGoToLine"; - this.Text = "NppDockableForm"; - this.VisibleChanged += new System.EventHandler(this.FrmGoToLineVisibleChanged); - this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.frmGoToLine_KeyDown); - this.ResumeLayout(false); - this.PerformLayout(); + this.label1 = new System.Windows.Forms.Label(); + this.button1 = new System.Windows.Forms.Button(); + this.textBox1 = new System.Windows.Forms.TextBox(); + this.DarkModeTestFormButton = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(16, 11); + this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(66, 16); + this.label1.TabIndex = 0; + this.label1.Text = "Go to line:"; + // + // button1 + // + this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.button1.Location = new System.Drawing.Point(20, 39); + this.button1.Margin = new System.Windows.Forms.Padding(4); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(143, 28); + this.button1.TabIndex = 2; + this.button1.Text = "&Go"; + this.button1.UseVisualStyleBackColor = true; + this.button1.Click += new System.EventHandler(this.button1_Click); + this.button1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.frmGoToLine_KeyDown); + // + // textBox1 + // + this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.textBox1.Location = new System.Drawing.Point(97, 7); + this.textBox1.Margin = new System.Windows.Forms.Padding(4); + this.textBox1.Name = "textBox1"; + this.textBox1.Size = new System.Drawing.Size(64, 22); + this.textBox1.TabIndex = 1; + this.textBox1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.frmGoToLine_KeyDown); + this.textBox1.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.textBox1_KeyPress); + // + // DarkModeTestFormButton + // + this.DarkModeTestFormButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.DarkModeTestFormButton.Location = new System.Drawing.Point(20, 84); + this.DarkModeTestFormButton.Name = "DarkModeTestFormButton"; + this.DarkModeTestFormButton.Size = new System.Drawing.Size(143, 32); + this.DarkModeTestFormButton.TabIndex = 3; + this.DarkModeTestFormButton.Text = "Dark mode test form"; + this.DarkModeTestFormButton.UseVisualStyleBackColor = true; + this.DarkModeTestFormButton.Click += new System.EventHandler(this.DarkModeTestFormButton_Click); + // + // frmGoToLine + // + this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(197, 134); + this.Controls.Add(this.DarkModeTestFormButton); + this.Controls.Add(this.textBox1); + this.Controls.Add(this.button1); + this.Controls.Add(this.label1); + this.Margin = new System.Windows.Forms.Padding(4); + this.Name = "frmGoToLine"; + this.Text = "NppDockableForm"; + this.VisibleChanged += new System.EventHandler(this.FrmGoToLineVisibleChanged); + this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.frmGoToLine_KeyDown); + this.ResumeLayout(false); + this.PerformLayout(); + } #endregion @@ -87,9 +108,6 @@ private void InitializeComponent() private System.Windows.Forms.Label label1; private System.Windows.Forms.Button button1; internal System.Windows.Forms.TextBox textBox1; - - - - - } + private System.Windows.Forms.Button DarkModeTestFormButton; + } } \ No newline at end of file diff --git a/Demo Plugin/NppManagedPluginDemo/Forms/frmGoToLine.resx b/Demo Plugin/NppManagedPluginDemo/Forms/frmGoToLine.resx index 7080a7d..1af7de1 100644 --- a/Demo Plugin/NppManagedPluginDemo/Forms/frmGoToLine.resx +++ b/Demo Plugin/NppManagedPluginDemo/Forms/frmGoToLine.resx @@ -112,9 +112,9 @@ 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 \ No newline at end of file diff --git a/Visual Studio Project Template C#/$projectname$.csproj b/Visual Studio Project Template C#/$projectname$.csproj index 974ba5c..2356549 100644 --- a/Visual Studio Project Template C#/$projectname$.csproj +++ b/Visual Studio Project Template C#/$projectname$.csproj @@ -73,6 +73,7 @@ + diff --git a/Visual Studio Project Template C#/PluginInfrastructure/DarkMode.cs b/Visual Studio Project Template C#/PluginInfrastructure/DarkMode.cs new file mode 100644 index 0000000..41354da --- /dev/null +++ b/Visual Studio Project Template C#/PluginInfrastructure/DarkMode.cs @@ -0,0 +1,56 @@ +using System; +using System.Drawing; +using System.Runtime.InteropServices; + +namespace Kbg.NppPluginNET.PluginInfrastructure +{ + /// + /// Holds the BGR values of the active dark mode theme. + /// + /// + [StructLayout(LayoutKind.Sequential)] + public struct DarkModeColors + { + public int Background; + public int SofterBackground; + public int HotBackground; + public int PureBackground; + public int ErrorBackground; + public int Text; + public int DarkerText; + public int DisabledText; + public int LinkText; + public int Edge; + public int HotEdge; + public int DisabledEdge; + } + + /// + /// Extends with methods implementing Npp's dark mode API. + /// + public partial class NotepadPPGateway : INotepadPPGateway + { + public IntPtr GetDarkModeColors() + { + DarkModeColors darkModeColors = new DarkModeColors(); + IntPtr _cbSize = new IntPtr(Marshal.SizeOf(darkModeColors)); + IntPtr _ptrDarkModeColors = Marshal.AllocHGlobal(_cbSize); + Win32.SendMessage(PluginBase.nppData._nppHandle, (uint) NppMsg.NPPM_GETDARKMODECOLORS, _cbSize, _ptrDarkModeColors); + return _ptrDarkModeColors; + } + + public bool IsDarkModeEnabled() + { + IntPtr result = Win32.SendMessage(PluginBase.nppData._nppHandle, (uint) NppMsg.NPPM_ISDARKMODEENABLED, Unused, Unused); + return ((int)result == 1); + } + } + + static class NppDarkMode + { + public static Color BGRToColor(int bgr) + { + return Color.FromArgb((bgr & 0xFF), ((bgr >> 8) & 0xFF), ((bgr >> 16) & 0xFF)); + } + } +} \ No newline at end of file diff --git a/Visual Studio Project Template C#/PluginInfrastructure/Docking_h.cs b/Visual Studio Project Template C#/PluginInfrastructure/Docking_h.cs index bb256da..dacdb9c 100644 --- a/Visual Studio Project Template C#/PluginInfrastructure/Docking_h.cs +++ b/Visual Studio Project Template C#/PluginInfrastructure/Docking_h.cs @@ -29,6 +29,7 @@ public enum NppTbMsg : uint DWS_ICONTAB = 0x00000001, // Icon for tabs are available DWS_ICONBAR = 0x00000002, // Icon for icon bar are available (currently not supported) DWS_ADDINFO = 0x00000004, // Additional information are in use + DWS_USEOWNDARKMODE = 0x00000008, // Use plugin's own dark mode DWS_PARAMSALL = (DWS_ICONTAB | DWS_ICONBAR | DWS_ADDINFO), // default docking values for first call of plugin diff --git a/Visual Studio Project Template C#/PluginInfrastructure/Msgs_h.cs b/Visual Studio Project Template C#/PluginInfrastructure/Msgs_h.cs index 214a73c..241ef45 100644 --- a/Visual Studio Project Template C#/PluginInfrastructure/Msgs_h.cs +++ b/Visual Studio Project Template C#/PluginInfrastructure/Msgs_h.cs @@ -560,6 +560,21 @@ public enum NppMsg : uint /// NPPM_ADDTOOLBARICON_FORDARKMODE = Constants.NPPMSG + 101, + /// + /// bool NPPM_ISDARKMODEENABLED(0, 0) + /// Returns true when Notepad++ Dark Mode is enabled, false when it is not. + /// + /// + NPPM_ISDARKMODEENABLED = (Constants.NPPMSG + 107), + + /// + /// bool NPPM_GETDARKMODECOLORS (size_t cbSize, NppDarkMode::Colors* returnColors) + /// - cbSize must be filled with sizeof(NppDarkMode::Colors). + /// - returnColors must be a pre-allocated NppDarkMode::Colors struct. + /// Returns true when successful, false otherwise. + /// + NPPM_GETDARKMODECOLORS = (Constants.NPPMSG + 108), + RUNCOMMAND_USER = Constants.WM_USER + 3000, NPPM_GETFULLCURRENTPATH = RUNCOMMAND_USER + FULL_CURRENT_PATH, NPPM_GETCURRENTDIRECTORY = RUNCOMMAND_USER + CURRENT_DIRECTORY, @@ -805,6 +820,14 @@ public enum NppMsg : uint /// NPPN_FILEDELETED = NPPN_FIRST + 26, + /// + /// To notify plugins that Dark Mode was enabled/disabled + /// scnNotification->nmhdr.code = NPPN_DARKMODECHANGED; + /// scnNotification->nmhdr.hwndFrom = hwndNpp; + /// scnNotification->nmhdr.idFrom = 0; + /// + NPPN_DARKMODECHANGED = (NPPN_FIRST + 27) + /* --Autogenerated -- end of section automatically generated from notepad-plus-plus\PowerEditor\src\MISC\PluginsManager\Notepad_plus_msgs.h * */ } } diff --git a/Visual Studio Project Template C#/PluginInfrastructure/NotepadPPGateway.cs b/Visual Studio Project Template C#/PluginInfrastructure/NotepadPPGateway.cs index ff11162..eb0ced6 100644 --- a/Visual Studio Project Template C#/PluginInfrastructure/NotepadPPGateway.cs +++ b/Visual Studio Project Template C#/PluginInfrastructure/NotepadPPGateway.cs @@ -13,6 +13,8 @@ public interface INotepadPPGateway void AddToolbarIcon(int funcItemsIndex, toolbarIcons icon); void AddToolbarIcon(int funcItemsIndex, Bitmap icon); + bool IsDarkModeEnabled(); + IntPtr GetDarkModeColors(); string GetNppPath(); string GetPluginConfigPath(); string GetCurrentFilePath(); @@ -25,7 +27,7 @@ public interface INotepadPPGateway /// This class holds helpers for sending messages defined in the Msgs_h.cs file. It is at the moment /// incomplete. Please help fill in the blanks. /// - public class NotepadPPGateway : INotepadPPGateway + public partial class NotepadPPGateway : INotepadPPGateway { private const int Unused = 0; From 16d35161bfad02813a2a1ffe48713d395416d0ca Mon Sep 17 00:00:00 2001 From: molsonkiko <46202915+molsonkiko@users.noreply.github.com> Date: Mon, 19 Jun 2023 20:53:51 -0700 Subject: [PATCH 2/2] Fix csproj, improve dark mode toggling 1. Add automatic handling of GroupBoxes, DataGridViews 2. Fix problems with .csproj caused by rebase --- Demo Plugin/NppManagedPluginDemo/Demo.cs | 92 +++++++++++----- .../Forms/DarkModeTestForm.Designer.cs | 101 ++++++++++++++---- .../Forms/DarkModeTestForm.cs | 7 +- .../Forms/DarkModeTestForm.resx | 20 +++- .../NppManagedPluginDemo.csproj | 13 +++ 5 files changed, 183 insertions(+), 50 deletions(-) diff --git a/Demo Plugin/NppManagedPluginDemo/Demo.cs b/Demo Plugin/NppManagedPluginDemo/Demo.cs index c975eb4..07e39cd 100644 --- a/Demo Plugin/NppManagedPluginDemo/Demo.cs +++ b/Demo Plugin/NppManagedPluginDemo/Demo.cs @@ -205,44 +205,56 @@ static internal void PluginCleanUp() /// /// a Windows Form /// is Notepad++ dark mode on? - static internal void ToggleDarkMode(Form form, bool isDark) + static internal void ToggleDarkMode(Control ctrl, bool isDark) { - if (form == null) + if (ctrl == null) return; IntPtr themePtr = notepad.GetDarkModeColors(); if (isDark && themePtr == IntPtr.Zero) return; var theme = (DarkModeColors)Marshal.PtrToStructure(themePtr, typeof(DarkModeColors)); - foreach (Form childForm in form.OwnedForms) + if (ctrl is Form form) { - // allow possibility that some forms will have other child forms - // JsonTools does this in a couple of places - ToggleDarkMode(childForm, isDark); + foreach (Form childForm in form.OwnedForms) + { + // allow possibility that some forms will have other child forms + // JsonTools does this in a couple of places + ToggleDarkMode(childForm, isDark); + } } if (isDark) { - form.BackColor = NppDarkMode.BGRToColor(theme.Background); - form.ForeColor = NppDarkMode.BGRToColor(theme.Text); + ctrl.BackColor = NppDarkMode.BGRToColor(theme.Background); + ctrl.ForeColor = NppDarkMode.BGRToColor(theme.Text); } else { - form.ResetForeColor(); - form.ResetBackColor(); + ctrl.ResetForeColor(); + ctrl.ResetBackColor(); } - foreach (Control ctrl in form.Controls) + foreach (Control child in ctrl.Controls) { if (isDark) { // this doesn't actually make disabled controls have different colors // windows forms don't make it easy for the user to choose the // color of a disabled control. See https://stackoverflow.com/questions/136129/windows-forms-how-do-you-change-the-font-color-for-a-disabled-label - var textTheme = ctrl.Enabled ? theme.Text : theme.DisabledText; - if (ctrl is Button btn) + var textTheme = child.Enabled ? theme.Text : theme.DisabledText; + Color foreColor = NppDarkMode.BGRToColor(textTheme); + Color backColor = NppDarkMode.BGRToColor(theme.PureBackground); + Color InBetween = Color.FromArgb( + foreColor.R / 4 + 3 * backColor.R / 4, + foreColor.G / 4 + 3 * backColor.G / 4, + foreColor.B / 4 + 3 * backColor.B / 4 + ); + if (child is GroupBox) + ToggleDarkMode(child, isDark); + else if (child is Button btn) { btn.BackColor = NppDarkMode.BGRToColor(theme.SofterBackground); - btn.ForeColor = NppDarkMode.BGRToColor(textTheme); + btn.ForeColor = foreColor; } - else if (ctrl is LinkLabel llbl) + else if (child is LinkLabel llbl) { llbl.BackColor = NppDarkMode.BGRToColor(theme.ErrorBackground); llbl.ForeColor = NppDarkMode.BGRToColor(theme.DarkerText); @@ -251,36 +263,60 @@ static internal void ToggleDarkMode(Form form, bool isDark) llbl.VisitedLinkColor = NppDarkMode.BGRToColor(theme.DarkerText); } // other common text-based controls - else if (ctrl is TextBox - || ctrl is Label - || ctrl is ListBox - || ctrl is ComboBox) + else if (child is TextBox + || child is Label + || child is ListBox + || child is ComboBox) { - ctrl.BackColor = NppDarkMode.BGRToColor(theme.PureBackground); - ctrl.ForeColor = NppDarkMode.BGRToColor(textTheme); + child.BackColor = backColor; + child.ForeColor = foreColor; } - else if (ctrl is TreeView tv) + else if (child is TreeView tv) { tv.BackColor = NppDarkMode.BGRToColor(theme.HotBackground); - tv.ForeColor = NppDarkMode.BGRToColor(textTheme); + tv.ForeColor = foreColor; + } + else if (child is DataGridView dgv) + { + dgv.EnableHeadersVisualStyles = false; + dgv.BackgroundColor = InBetween; + dgv.ForeColor = foreColor; + dgv.GridColor = foreColor; + dgv.ColumnHeadersDefaultCellStyle.ForeColor = foreColor; + dgv.ColumnHeadersDefaultCellStyle.BackColor = backColor; + dgv.RowHeadersDefaultCellStyle.ForeColor = foreColor; + dgv.RowHeadersDefaultCellStyle.BackColor = backColor; + dgv.RowsDefaultCellStyle.ForeColor = foreColor; + dgv.RowsDefaultCellStyle.BackColor = backColor; } else { // other controls I haven't thought of yet - ctrl.BackColor = NppDarkMode.BGRToColor(theme.SofterBackground); - ctrl.ForeColor = NppDarkMode.BGRToColor(textTheme); + child.BackColor = NppDarkMode.BGRToColor(theme.SofterBackground); + child.ForeColor = foreColor; } } else // normal light mode { - ctrl.ResetForeColor(); - ctrl.ResetBackColor(); - if (ctrl is LinkLabel llbl) + child.ResetForeColor(); + child.ResetBackColor(); + if (child is GroupBox) + ToggleDarkMode(child, isDark); + if (child is LinkLabel llbl) { llbl.LinkColor = Color.Blue; llbl.ActiveLinkColor = Color.Red; llbl.VisitedLinkColor = Color.Purple; } + else if (child is DataGridView dgv) + { + dgv.EnableHeadersVisualStyles = true; + dgv.BackgroundColor = SystemColors.ControlDark; + dgv.ForeColor = SystemColors.ControlText; + dgv.GridColor = SystemColors.ControlLight; + dgv.RowsDefaultCellStyle.ForeColor = SystemColors.ControlText; + dgv.RowsDefaultCellStyle.BackColor = SystemColors.Window; + } } } Marshal.FreeHGlobal(themePtr); diff --git a/Demo Plugin/NppManagedPluginDemo/Forms/DarkModeTestForm.Designer.cs b/Demo Plugin/NppManagedPluginDemo/Forms/DarkModeTestForm.Designer.cs index e223178..62be11c 100644 --- a/Demo Plugin/NppManagedPluginDemo/Forms/DarkModeTestForm.Designer.cs +++ b/Demo Plugin/NppManagedPluginDemo/Forms/DarkModeTestForm.Designer.cs @@ -45,20 +45,27 @@ private void InitializeComponent() System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DarkModeTestForm)); this.button1 = new System.Windows.Forms.Button(); this.treeView1 = new System.Windows.Forms.TreeView(); + this.imageList1 = new System.Windows.Forms.ImageList(this.components); this.listBox1 = new System.Windows.Forms.ListBox(); this.Title = new System.Windows.Forms.Label(); this.comboBox1 = new System.Windows.Forms.ComboBox(); this.linkLabel1 = new System.Windows.Forms.LinkLabel(); this.label1 = new System.Windows.Forms.Label(); this.checkBox1 = new System.Windows.Forms.CheckBox(); - this.imageList1 = new System.Windows.Forms.ImageList(this.components); this.textBox1 = new System.Windows.Forms.TextBox(); this.textBox2 = new System.Windows.Forms.TextBox(); + this.dataGridView1 = new System.Windows.Forms.DataGridView(); + this.Column1 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.Column2 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.Column3 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit(); + this.groupBox1.SuspendLayout(); this.SuspendLayout(); // // button1 // - this.button1.Location = new System.Drawing.Point(217, 301); + this.button1.Location = new System.Drawing.Point(217, 385); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(75, 23); this.button1.TabIndex = 0; @@ -99,6 +106,14 @@ private void InitializeComponent() this.treeView1.Size = new System.Drawing.Size(178, 135); this.treeView1.TabIndex = 1; // + // imageList1 + // + this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream"))); + this.imageList1.TransparentColor = System.Drawing.Color.Transparent; + this.imageList1.Images.SetKeyName(0, "star.png"); + this.imageList1.Images.SetKeyName(1, "star_black.ico"); + this.imageList1.Images.SetKeyName(2, "star_white.ico"); + // // listBox1 // this.listBox1.FormattingEnabled = true; @@ -134,7 +149,7 @@ private void InitializeComponent() "is", "a", "comboBox"}); - this.comboBox1.Location = new System.Drawing.Point(217, 98); + this.comboBox1.Location = new System.Drawing.Point(17, 27); this.comboBox1.Name = "comboBox1"; this.comboBox1.Size = new System.Drawing.Size(121, 24); this.comboBox1.TabIndex = 4; @@ -143,7 +158,7 @@ private void InitializeComponent() // this.linkLabel1.AutoSize = true; this.linkLabel1.LinkArea = new System.Windows.Forms.LinkArea(0, 10); - this.linkLabel1.Location = new System.Drawing.Point(376, 275); + this.linkLabel1.Location = new System.Drawing.Point(376, 359); this.linkLabel1.Name = "linkLabel1"; this.linkLabel1.Size = new System.Drawing.Size(145, 49); this.linkLabel1.TabIndex = 5; @@ -155,7 +170,7 @@ private void InitializeComponent() // label1 // this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(36, 308); + this.label1.Location = new System.Drawing.Point(36, 392); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(105, 16); this.label1.TabIndex = 6; @@ -164,24 +179,16 @@ private void InitializeComponent() // checkBox1 // this.checkBox1.AutoSize = true; - this.checkBox1.Location = new System.Drawing.Point(179, 265); + this.checkBox1.Location = new System.Drawing.Point(179, 349); this.checkBox1.Name = "checkBox1"; this.checkBox1.Size = new System.Drawing.Size(173, 20); this.checkBox1.TabIndex = 7; this.checkBox1.Text = "checkBox1 looks good?"; this.checkBox1.UseVisualStyleBackColor = true; // - // imageList1 - // - this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream"))); - this.imageList1.TransparentColor = System.Drawing.Color.Transparent; - this.imageList1.Images.SetKeyName(0, "star.png"); - this.imageList1.Images.SetKeyName(1, "star_black.ico"); - this.imageList1.Images.SetKeyName(2, "star_white.ico"); - // // textBox1 // - this.textBox1.Location = new System.Drawing.Point(217, 190); + this.textBox1.Location = new System.Drawing.Point(17, 119); this.textBox1.Multiline = true; this.textBox1.Name = "textBox1"; this.textBox1.Size = new System.Drawing.Size(121, 23); @@ -191,29 +198,78 @@ private void InitializeComponent() // textBox2 // this.textBox2.Enabled = false; - this.textBox2.Location = new System.Drawing.Point(217, 144); + this.textBox2.Location = new System.Drawing.Point(17, 73); this.textBox2.Name = "textBox2"; this.textBox2.Size = new System.Drawing.Size(121, 22); this.textBox2.TabIndex = 9; this.textBox2.Text = "disabled textbox"; // + // dataGridView1 + // + this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.Column1, + this.Column2, + this.Column3}); + this.dataGridView1.Location = new System.Drawing.Point(12, 241); + this.dataGridView1.Name = "dataGridView1"; + this.dataGridView1.RowHeadersWidth = 51; + this.dataGridView1.RowTemplate.Height = 24; + this.dataGridView1.Size = new System.Drawing.Size(470, 84); + this.dataGridView1.TabIndex = 10; + // + // Column1 + // + this.Column1.HeaderText = "Column1"; + this.Column1.MinimumWidth = 6; + this.Column1.Name = "Column1"; + this.Column1.Width = 90; + // + // Column2 + // + this.Column2.HeaderText = "This is a DataGridView"; + this.Column2.MinimumWidth = 6; + this.Column2.Name = "Column2"; + this.Column2.Width = 200; + // + // Column3 + // + this.Column3.HeaderText = "Column3"; + this.Column3.MinimumWidth = 6; + this.Column3.Name = "Column3"; + this.Column3.Width = 90; + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.textBox2); + this.groupBox1.Controls.Add(this.textBox1); + this.groupBox1.Controls.Add(this.comboBox1); + this.groupBox1.Location = new System.Drawing.Point(208, 77); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(144, 158); + this.groupBox1.TabIndex = 11; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "groupBox1"; + // // DarkModeTestForm // this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(577, 358); - this.Controls.Add(this.textBox2); - this.Controls.Add(this.textBox1); + this.ClientSize = new System.Drawing.Size(577, 429); + this.Controls.Add(this.groupBox1); + this.Controls.Add(this.dataGridView1); this.Controls.Add(this.checkBox1); this.Controls.Add(this.label1); this.Controls.Add(this.linkLabel1); - this.Controls.Add(this.comboBox1); this.Controls.Add(this.Title); this.Controls.Add(this.listBox1); this.Controls.Add(this.treeView1); this.Controls.Add(this.button1); this.Name = "DarkModeTestForm"; this.Text = "DarkModeTestForm"; + ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit(); + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); @@ -232,5 +288,10 @@ private void InitializeComponent() private System.Windows.Forms.ImageList imageList1; private System.Windows.Forms.TextBox textBox1; private System.Windows.Forms.TextBox textBox2; + private System.Windows.Forms.DataGridView dataGridView1; + private System.Windows.Forms.DataGridViewTextBoxColumn Column1; + private System.Windows.Forms.DataGridViewTextBoxColumn Column2; + private System.Windows.Forms.DataGridViewTextBoxColumn Column3; + private System.Windows.Forms.GroupBox groupBox1; } } \ No newline at end of file diff --git a/Demo Plugin/NppManagedPluginDemo/Forms/DarkModeTestForm.cs b/Demo Plugin/NppManagedPluginDemo/Forms/DarkModeTestForm.cs index a0aeb39..95a166f 100644 --- a/Demo Plugin/NppManagedPluginDemo/Forms/DarkModeTestForm.cs +++ b/Demo Plugin/NppManagedPluginDemo/Forms/DarkModeTestForm.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using System.ComponentModel; -using System.Data; using System.Drawing; using System.Linq; using System.Text; @@ -18,6 +17,12 @@ public DarkModeTestForm() var notepad = new NotepadPPGateway(); Main.ToggleDarkMode(this, notepad.IsDarkModeEnabled()); comboBox1.SelectedIndex = 0; + DataGridViewRow row = new DataGridViewRow(); + row.CreateCells(dataGridView1); + row.Cells[0].Value = "Value1"; + row.Cells[1].Value = "Should look pretty"; + row.Cells[2].Value = "Value3"; + dataGridView1.Rows.Add(row); } private void LinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) diff --git a/Demo Plugin/NppManagedPluginDemo/Forms/DarkModeTestForm.resx b/Demo Plugin/NppManagedPluginDemo/Forms/DarkModeTestForm.resx index 811e322..9914dc2 100644 --- a/Demo Plugin/NppManagedPluginDemo/Forms/DarkModeTestForm.resx +++ b/Demo Plugin/NppManagedPluginDemo/Forms/DarkModeTestForm.resx @@ -125,7 +125,7 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADw - CgAAAk1TRnQBSQFMAgEBAwEAAQgBAAEIAQABEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo + CgAAAk1TRnQBSQFMAgEBAwEAARABAAEQAQABEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo AwABQAMAARADAAEBAQABCAYAAQQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA @@ -174,4 +174,22 @@ AgABgAEBAccB8wHHAfMCAAHgAQcB4AEHAeABBwIAAfABDwH4AR8B+AEfAgAL + + True + + + True + + + True + + + True + + + True + + + True + \ No newline at end of file diff --git a/Demo Plugin/NppManagedPluginDemo/NppManagedPluginDemo.csproj b/Demo Plugin/NppManagedPluginDemo/NppManagedPluginDemo.csproj index 77e3ad2..55e9cc4 100644 --- a/Demo Plugin/NppManagedPluginDemo/NppManagedPluginDemo.csproj +++ b/Demo Plugin/NppManagedPluginDemo/NppManagedPluginDemo.csproj @@ -117,12 +117,21 @@ PluginInfrastructure\NanInf.cs + + PluginInfrastructure\DarkMode.cs + Form frmGoToLine.cs + + Form + + + DarkModeTestForm.cs + @@ -144,6 +153,10 @@ frmGoToLine.cs Designer + + DarkModeTestForm.cs + Designer + Designer ResXFileCodeGenerator