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")]