diff --git a/Demo Plugin/NppManagedPluginDemo/Demo.cs b/Demo Plugin/NppManagedPluginDemo/Demo.cs index 382d0fe..07e39cd 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,140 @@ 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(Control ctrl, bool isDark) + { + if (ctrl == null) + return; + IntPtr themePtr = notepad.GetDarkModeColors(); + if (isDark && themePtr == IntPtr.Zero) + return; + var theme = (DarkModeColors)Marshal.PtrToStructure(themePtr, typeof(DarkModeColors)); + if (ctrl is Form form) + { + 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) + { + ctrl.BackColor = NppDarkMode.BGRToColor(theme.Background); + ctrl.ForeColor = NppDarkMode.BGRToColor(theme.Text); + } + else + { + ctrl.ResetForeColor(); + ctrl.ResetBackColor(); + } + 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 = 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 = foreColor; + } + else if (child 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 (child is TextBox + || child is Label + || child is ListBox + || child is ComboBox) + { + child.BackColor = backColor; + child.ForeColor = foreColor; + } + else if (child is TreeView tv) + { + tv.BackColor = NppDarkMode.BGRToColor(theme.HotBackground); + 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 + child.BackColor = NppDarkMode.BGRToColor(theme.SofterBackground); + child.ForeColor = foreColor; + } + } + else // normal light mode + { + 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); + } #endregion #region " Menu functions " @@ -443,6 +585,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..62be11c --- /dev/null +++ b/Demo Plugin/NppManagedPluginDemo/Forms/DarkModeTestForm.Designer.cs @@ -0,0 +1,297 @@ +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.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.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, 385); + 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; + // + // 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; + 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(17, 27); + 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, 359); + 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, 392); + 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, 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; + // + // textBox1 + // + 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); + this.textBox1.TabIndex = 8; + this.textBox1.Text = "textBox1"; + // + // textBox2 + // + this.textBox2.Enabled = false; + 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, 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.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(); + + } + + #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; + 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 new file mode 100644 index 0000000..95a166f --- /dev/null +++ b/Demo Plugin/NppManagedPluginDemo/Forms/DarkModeTestForm.cs @@ -0,0 +1,33 @@ +using Kbg.NppPluginNET.PluginInfrastructure; +using System; +using System.Collections.Generic; +using System.ComponentModel; +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; + 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) + { + 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..9914dc2 --- /dev/null +++ b/Demo Plugin/NppManagedPluginDemo/Forms/DarkModeTestForm.resx @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + CgAAAk1TRnQBSQFMAgEBAwEAARABAAEQAQABEAEAARABAAT/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 + + + + True + + + True + + + True + + + True + + + True + + + True + + \ 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/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 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;