From 58f41bf8b65be87406b903165b4f827fc97928b8 Mon Sep 17 00:00:00 2001 From: molsonkiko <46202915+molsonkiko@users.noreply.github.com> Date: Wed, 21 Feb 2024 19:46:59 -0800 Subject: [PATCH] add allocate indicators demo --- CHANGELOG.md | 1 + NppCSharpPluginPack/Main.cs | 118 ++++++++++++++++++ .../PluginInfrastructure/Msgs_h.cs | 16 +++ .../PluginInfrastructure/NotepadPPGateway.cs | 29 ++++- .../Properties/AssemblyInfo.cs | 4 +- 5 files changed, 165 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index de7d439..ab91575 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). 1. Ported over (from kbilsted's old template) the [ToolsForMaintainersOfTheProjectTemplate](/ToolsForMaintainersOfTheProjectTemplate/) folder for updating some of the [PluginInfrastructure](/NppCSharpPluginPack/PluginInfrastructure/) files to stay up to date with Notepad++. 2. Added new [PopupDialog form](/docs/README.md#popup-dialog), which demonstrates how to configure a pop-up dialog that has select-able fields like textboxes or buttons. +3. Added new `Allocate indicators demo`, demonstrating how to allocate and use indicators to style text. ### Changed diff --git a/NppCSharpPluginPack/Main.cs b/NppCSharpPluginPack/Main.cs index 20280b5..2a30599 100644 --- a/NppCSharpPluginPack/Main.cs +++ b/NppCSharpPluginPack/Main.cs @@ -35,6 +35,9 @@ class Main public static bool bufferFinishedOpening; public static string activeFname = null; public static bool isDocTypeHTML = false; + // indicator things + private static int firstIndicator = -1; + private static int lastIndicator = -1; // forms public static SelectionRememberingForm selectionRememberingForm = null; static internal int IdAboutForm = -1; @@ -88,6 +91,8 @@ static internal void CommandMenuInit() PluginBase.SetCommand(18, "Save Current Session Demo", SaveCurrentSessionDemo); PluginBase.SetCommand(19, "Print Scroll and Row Information", PrintScrollInformation); PluginBase.SetCommand(20, "Open a pop-up dialog", OpenPopupDialog); + PluginBase.SetCommand(21, "---", null); + PluginBase.SetCommand(22, "Allocate indicators demo", AllocateIndicatorsDemo); } @@ -463,6 +468,119 @@ private static void ShowFilesOpenedAndClosedThisSession() Npp.editor.SetText(sb.ToString()); } + /// + /// this shows how to allocate indicators (note: this only works in Notepad++ 8.5.6 or newer)

+ /// and also provides a very simple example of how to style a region of text with indicators. + ///
+ private static void AllocateIndicatorsDemo() + { + var dialog = new Form + { + Text = "Allocate indicators demo", + ClientSize = new Size(300, 220), + MinimumSize = new Size(300, 220), + ShowIcon = false, + AutoScaleMode = AutoScaleMode.Font, + AutoScaleDimensions = new SizeF(6F, 13F), + ShowInTaskbar = false, + StartPosition = FormStartPosition.CenterParent, + Controls = + { + new Label + { + Name = "AllocateIndicatorsTextBoxLabel", + Text = "Choose a positive integer", + Anchor = AnchorStyles.Bottom | AnchorStyles.Right, + AutoSize = true, + Location = new Point(60, 50), + }, + new TextBox + { + Name = "AllocateIndicatorsTextBox", + Text = "1", + Anchor = AnchorStyles.Bottom | AnchorStyles.Right, + Size = new Size(75, 23), + Location = new Point(100, 100) + }, + new Button + { + Name = "Ok", + Text = "&Ok", + Anchor = AnchorStyles.Bottom | AnchorStyles.Right, + Size = new Size(75, 23), + Location = new Point(50, 160), + UseVisualStyleBackColor = true + }, + new Button + { + Name = "Show", + Text = "&Show", + Anchor = AnchorStyles.Bottom | AnchorStyles.Right, + Size = new Size(75, 23), + Location = new Point(175, 160), + UseVisualStyleBackColor = true + }, + } + }; + + dialog.Controls["Show"].Click += (a, b) => dialog.Close(); + dialog.Controls["Ok"].Click += (a, b) => + { + string allocatorIndicatorsText = dialog.Controls["AllocateIndicatorsTextBox"].Text; + bool failure = false; + string errorMessage = "Number of indicators must be a positive integer, not " + allocatorIndicatorsText; + try + { + int numberOfIndicators = int.Parse(allocatorIndicatorsText); + if (numberOfIndicators < 1) + failure = true; + if (Npp.notepad.AllocateIndicators(numberOfIndicators, out int[] indicators)) + { + string indicatorsStr = string.Join(", ", indicators.Select(x => x.ToString()).ToArray()); + if (indicators.Length > 0) + { + if (firstIndicator == -1) + firstIndicator = indicators[0]; + lastIndicator = indicators[indicators.Length - 1]; + } + MessageBox.Show($"Was able to allocate the following {numberOfIndicators} indicators: {indicatorsStr}", + $"Successfully allocated {numberOfIndicators} indicators", + MessageBoxButtons.OK, MessageBoxIcon.Information); + } + else + { + failure = true; + errorMessage = $"Notepad++ failed to find {numberOfIndicators} consecutive unallocated indicators starting at {lastIndicator + 1}, but there was no error"; + } + } + catch + { + failure = true; + } + if (failure) + MessageBox.Show(errorMessage, + "Could not allocate indicators", + MessageBoxButtons.OK, MessageBoxIcon.Error); + }; + dialog.ShowDialog(); + if (firstIndicator != -1) + { + string text = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + Npp.notepad.FileNew(); + Npp.editor.SetText(text); + for (int ii = firstIndicator; ii <= lastIndicator; ii++) + { + Npp.editor.SetIndicatorCurrent(ii); + Npp.editor.IndicSetStyle(ii, IndicatorStyle.SQUIGGLE); + Npp.editor.IndicSetFore(ii, new Colour(0xff, 0, 0)); + Npp.editor.IndicatorFillRange(ii, 1); + } + MessageBox.Show($"Characters {firstIndicator}-{lastIndicator} are styled by indicators {firstIndicator}-{lastIndicator}, which have been allocated by the preceding dialog this session.", + "Showing which indicators are in use", + MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } + //form opening stuff static void OpenSettings() diff --git a/NppCSharpPluginPack/PluginInfrastructure/Msgs_h.cs b/NppCSharpPluginPack/PluginInfrastructure/Msgs_h.cs index 502266d..ef49b20 100644 --- a/NppCSharpPluginPack/PluginInfrastructure/Msgs_h.cs +++ b/NppCSharpPluginPack/PluginInfrastructure/Msgs_h.cs @@ -573,6 +573,22 @@ public enum NppMsg : uint /// NPPM_ADDTOOLBARICON_FORDARKMODE = Constants.NPPMSG + 101, + // BOOL NPPM_ALLOCATEINDICATOR(int numberRequested, int* startNumber) + // Allocates an indicator number to a plugin: if a plugin needs to add an indicator, + // it has to use this message to get the indicator number, in order to prevent a conflict with the other plugins. + // wParam[in]: numberRequested is the number of ID you request for the reservation + // lParam[out]: startNumber will be set to the initial command ID if successful + // Return TRUE if successful, FALSE otherwise. startNumber will also be set to 0 if unsuccessful + // + // Example: If a plugin needs 1 indicator ID, the following code can be used : + // + // int idBegin; + // BOOL isAllocatedSuccessful = ::SendMessage(nppData._nppHandle, NPPM_ALLOCATEINDICATOR, 1, &idBegin); + // + // if isAllocatedSuccessful is TRUE, and value of idBegin is 7 + // then indicator ID 7 is preserved by Notepad++, and it is safe to be used by the plugin. + NPPM_ALLOCATEINDICATOR = Constants.NPPMSG + 113, + RUNCOMMAND_USER = Constants.WM_USER + 3000, NPPM_GETFULLCURRENTPATH = RUNCOMMAND_USER + FULL_CURRENT_PATH, NPPM_GETCURRENTDIRECTORY = RUNCOMMAND_USER + CURRENT_DIRECTORY, diff --git a/NppCSharpPluginPack/PluginInfrastructure/NotepadPPGateway.cs b/NppCSharpPluginPack/PluginInfrastructure/NotepadPPGateway.cs index 0f4be70..15ff954 100644 --- a/NppCSharpPluginPack/PluginInfrastructure/NotepadPPGateway.cs +++ b/NppCSharpPluginPack/PluginInfrastructure/NotepadPPGateway.cs @@ -41,6 +41,17 @@ public interface INotepadPPGateway /// /// the Handle attribute of a Windows form void RemoveModelessDialog(IntPtr formHandle); + /// + /// Introduced in Notepad++ 8.5.6.

+ /// NPPM_ALLOCATEINDICATOR: allocate one or more unused indicator IDs, + /// which can then be assigned styles and used to style regions of text.

+ /// returns false and sets indicators to null if numberOfIndicators is less than 1, or if the requested number of indicators could not be allocated.

+ /// Otherwise, returns true, and sets indicators to an array of numberOfIndicators indicator IDs.

+ /// See https://www.scintilla.org/ScintillaDoc.html#Indicators for more info on the indicator API. + ///
+ /// number of consecutive indicator IDs to allocate + /// + bool AllocateIndicators(int numberOfIndicators, out int[] indicators); } @@ -240,7 +251,23 @@ public void SetStatusBarSection(string message, StatusBarSection section) { Win32.SendMessage(PluginBase.nppData._nppHandle, (uint)NppMsg.NPPM_SETSTATUSBAR, (int)section, message); } - } + + public unsafe bool AllocateIndicators(int numberOfIndicators, out int[] indicators) + { + indicators = null; + if (numberOfIndicators < 1) + return false; + indicators = new int[numberOfIndicators]; + fixed (int * indicatorsPtr = indicators) + { + IntPtr success = Win32.SendMessage(PluginBase.nppData._nppHandle, (uint)NppMsg.NPPM_ALLOCATEINDICATOR, (IntPtr)numberOfIndicators, (IntPtr)indicatorsPtr); + for (int ii = 1; ii < numberOfIndicators; ii++) + indicators[ii] = indicators[ii - 1] + 1; + return success != IntPtr.Zero; + } + } + + } /// /// This class holds helpers for sending messages defined in the Resource_h.cs file. It is at the moment diff --git a/NppCSharpPluginPack/Properties/AssemblyInfo.cs b/NppCSharpPluginPack/Properties/AssemblyInfo.cs index 43b38a2..6e007c6 100644 --- a/NppCSharpPluginPack/Properties/AssemblyInfo.cs +++ b/NppCSharpPluginPack/Properties/AssemblyInfo.cs @@ -28,5 +28,5 @@ // Build Number // Revision // -[assembly: AssemblyVersion("0.0.2.2")] -[assembly: AssemblyFileVersion("0.0.2.2")] +[assembly: AssemblyVersion("0.0.2.3")] +[assembly: AssemblyFileVersion("0.0.2.3")]