using Kbg.NppPluginNET.PluginInfrastructure; using MarkdownRenderer; using System; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; namespace NppMarkdownRenderer { internal static class PluginBridge { private static readonly IScintillaGateway CurrentEditor = new ScintillaGateway(PluginBase.GetCurrentScintilla()); private static readonly MarkdownRendererForm RendererForm = new MarkdownRendererForm(); // for get current editing file info private static readonly INotepadPPGateway Notepad = new NotepadPPGateway(); public static bool Enable { get; private set; } public static void SetupPluginMenu() { PluginBase.SetCommand(1, "Toggle Markdown Renderer", ShowMarkdownRenderer); } public static void SetupToolBarIcon() { var toolbarIcons = new toolbarIcons { hToolbarBmp = MarkdownRendererResources.MainIconBm16.GetHbitmap() }; var pTbIcons = Marshal.AllocHGlobal(Marshal.SizeOf(toolbarIcons)); Marshal.StructureToPtr(toolbarIcons, pTbIcons, false); Win32.SendMessage(PluginBase.nppData._nppHandle, (uint)NppMsg.NPPM_ADDTOOLBARICON, PluginBase._funcItems.Items[0]._cmdID, pTbIcons); Marshal.FreeHGlobal(pTbIcons); } private static void ShowMarkdownRenderer() { if (false == RendererForm.Created) { RendererForm.VisibleChanged += delegate { if (RendererForm.Visible) { FlushState(); UpdateText(); UpdateScroll(); Enable = true; Task.Factory.StartNew(() => { Thread.Sleep(100); CurrentEditor.SetFocus(true); }); } else { Enable = false; Win32.SendMessage(PluginBase.nppData._nppHandle, (uint)NppMsg.NPPM_SETMENUITEMCHECK, PluginBase._funcItems.Items[0]._cmdID, 0); } }; RendererForm.SizeChanged += delegate { CurrentEditor.SetFocus(true); }; // dlgID: the dlgDlg should be the index of funcItem where the current function pointer is in // this case is 15.. so the initial value of funcItem[15]._cmdID - not the updated internal one ! // uMask: define the default docking behaviour var nppTbData = new NppTbData { pszModuleName = AnyCpuBridgeMain.PluginName, hClient = RendererForm.Handle, pszName = RendererForm.Text, hIconTab = (uint)MarkdownRendererResources.MainIcon.Handle, uMask = NppTbMsg.DWS_DF_CONT_LEFT | NppTbMsg.DWS_ICONTAB | NppTbMsg.DWS_ICONBAR, dlgID = 1, }; var ptrNppTbData = Marshal.AllocHGlobal(Marshal.SizeOf(nppTbData)); Marshal.StructureToPtr(nppTbData, ptrNppTbData, false); Win32.SendMessage(PluginBase.nppData._nppHandle, (uint)NppMsg.NPPM_DMMREGASDCKDLG, IntPtr.Zero, ptrNppTbData); Win32.SendMessage(PluginBase.nppData._nppHandle, (uint)NppMsg.NPPM_SETMENUITEMCHECK, PluginBase._funcItems.Items[0]._cmdID, 1); Enable = true; } else { if (!RendererForm.Visible) { Win32.SendMessage(PluginBase.nppData._nppHandle, (uint)NppMsg.NPPM_DMMSHOW, 0, RendererForm.Handle); Win32.SendMessage(PluginBase.nppData._nppHandle, (uint)NppMsg.NPPM_SETMENUITEMCHECK, PluginBase._funcItems.Items[0]._cmdID, 1); Enable = true; } else { Enable = false; Win32.SendMessage(PluginBase.nppData._nppHandle, (uint)NppMsg.NPPM_DMMHIDE, 0, RendererForm.Handle); Win32.SendMessage(PluginBase.nppData._nppHandle, (uint)NppMsg.NPPM_SETMENUITEMCHECK, PluginBase._funcItems.Items[0]._cmdID, 0); } } } public static void FlushState() { CurrentEditor.SetScintillaHandle(PluginBase.GetCurrentScintilla()); } public static void UpdateText() { var filePath = Notepad.GetCurrentFilePath(); var mdText = true == filePath?.EndsWith(".md", StringComparison.InvariantCultureIgnoreCase) ? CurrentEditor.GetText(CurrentEditor.GetLength() + 1) : "ERROR: Only Markdown(*.md) supported"; RendererForm.PutMarkdown(mdText); } public static void UpdateScroll() { var scrollInfo = CurrentEditor.GetScrollInfo(Win32.ScrollInfoMask.SIF_RANGE | Win32.ScrollInfoMask.SIF_TRACKPOS | Win32.ScrollInfoMask.SIF_PAGE, Win32.ScrollInfoBar.SB_VERT); double totalRange = scrollInfo.nMax - scrollInfo.nMin + 1; double scrollRatio; // Is "Enable scrolling beyond last line" checked? if (CurrentEditor.GetEndAtLastLine() == false) { var actualThumbHeight = totalRange / (totalRange / scrollInfo.nPage - 1); var actualTrackPos = scrollInfo.nTrackPos * actualThumbHeight / scrollInfo.nPage; scrollRatio = Math.Min(1, actualTrackPos / (totalRange - actualThumbHeight)); } else { scrollRatio = scrollInfo.nTrackPos / (totalRange - scrollInfo.nPage); } RendererForm.ScrollToPercent(scrollRatio); } public static void Exit() { RendererForm.Close(); RendererForm.Dispose(); MarkdownRendererMain.Quit(); } } }