PluginBridge.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. using Kbg.NppPluginNET.PluginInfrastructure;
  2. using MarkdownRenderer;
  3. using System;
  4. using System.Runtime.InteropServices;
  5. using System.Threading;
  6. using System.Threading.Tasks;
  7. namespace NppMarkdownRenderer
  8. {
  9. internal static class PluginBridge
  10. {
  11. private static readonly IScintillaGateway CurrentEditor = new ScintillaGateway(PluginBase.GetCurrentScintilla());
  12. private static readonly MarkdownRendererForm RendererForm = new MarkdownRendererForm();
  13. // for get current editing file info
  14. private static readonly INotepadPPGateway Notepad = new NotepadPPGateway();
  15. public static bool Enable { get; private set; }
  16. public static void SetupPluginMenu()
  17. {
  18. PluginBase.SetCommand(1, "Toggle Markdown Renderer", ShowMarkdownRenderer);
  19. }
  20. public static void SetupToolBarIcon()
  21. {
  22. var toolbarIcons = new toolbarIcons { hToolbarBmp = MarkdownRendererResources.MainIconBm16.GetHbitmap() };
  23. var pTbIcons = Marshal.AllocHGlobal(Marshal.SizeOf(toolbarIcons));
  24. Marshal.StructureToPtr(toolbarIcons, pTbIcons, false);
  25. Win32.SendMessage(PluginBase.nppData._nppHandle, (uint)NppMsg.NPPM_ADDTOOLBARICON, PluginBase._funcItems.Items[0]._cmdID, pTbIcons);
  26. Marshal.FreeHGlobal(pTbIcons);
  27. }
  28. private static void ShowMarkdownRenderer()
  29. {
  30. if (false == RendererForm.Created)
  31. {
  32. RendererForm.VisibleChanged += delegate
  33. {
  34. if (RendererForm.Visible)
  35. {
  36. FlushState();
  37. UpdateText();
  38. UpdateScroll();
  39. Enable = true;
  40. Task.Factory.StartNew(() =>
  41. {
  42. Thread.Sleep(100);
  43. CurrentEditor.SetFocus(true);
  44. });
  45. }
  46. else
  47. {
  48. Enable = false;
  49. Win32.SendMessage(PluginBase.nppData._nppHandle, (uint)NppMsg.NPPM_SETMENUITEMCHECK, PluginBase._funcItems.Items[0]._cmdID, 0);
  50. }
  51. };
  52. RendererForm.SizeChanged += delegate
  53. {
  54. CurrentEditor.SetFocus(true);
  55. };
  56. // dlgID: the dlgDlg should be the index of funcItem where the current function pointer is in
  57. // this case is 15.. so the initial value of funcItem[15]._cmdID - not the updated internal one !
  58. // uMask: define the default docking behaviour
  59. var nppTbData = new NppTbData
  60. {
  61. pszModuleName = AnyCpuBridgeMain.PluginName,
  62. hClient = RendererForm.Handle,
  63. pszName = RendererForm.Text,
  64. hIconTab = (uint)MarkdownRendererResources.MainIcon.Handle,
  65. uMask = NppTbMsg.DWS_DF_CONT_LEFT | NppTbMsg.DWS_ICONTAB | NppTbMsg.DWS_ICONBAR,
  66. dlgID = 1,
  67. };
  68. var ptrNppTbData = Marshal.AllocHGlobal(Marshal.SizeOf(nppTbData));
  69. Marshal.StructureToPtr(nppTbData, ptrNppTbData, false);
  70. Win32.SendMessage(PluginBase.nppData._nppHandle, (uint)NppMsg.NPPM_DMMREGASDCKDLG, IntPtr.Zero, ptrNppTbData);
  71. Win32.SendMessage(PluginBase.nppData._nppHandle, (uint)NppMsg.NPPM_SETMENUITEMCHECK, PluginBase._funcItems.Items[0]._cmdID, 1);
  72. Enable = true;
  73. }
  74. else
  75. {
  76. if (!RendererForm.Visible)
  77. {
  78. Win32.SendMessage(PluginBase.nppData._nppHandle, (uint)NppMsg.NPPM_DMMSHOW, 0, RendererForm.Handle);
  79. Win32.SendMessage(PluginBase.nppData._nppHandle, (uint)NppMsg.NPPM_SETMENUITEMCHECK, PluginBase._funcItems.Items[0]._cmdID, 1);
  80. Enable = true;
  81. }
  82. else
  83. {
  84. Enable = false;
  85. Win32.SendMessage(PluginBase.nppData._nppHandle, (uint)NppMsg.NPPM_DMMHIDE, 0, RendererForm.Handle);
  86. Win32.SendMessage(PluginBase.nppData._nppHandle, (uint)NppMsg.NPPM_SETMENUITEMCHECK, PluginBase._funcItems.Items[0]._cmdID, 0);
  87. }
  88. }
  89. }
  90. public static void FlushState()
  91. {
  92. CurrentEditor.SetScintillaHandle(PluginBase.GetCurrentScintilla());
  93. }
  94. public static void UpdateText()
  95. {
  96. var filePath = Notepad.GetCurrentFilePath();
  97. var mdText = true == filePath?.EndsWith(".md", StringComparison.InvariantCultureIgnoreCase) ? CurrentEditor.GetText(CurrentEditor.GetLength() + 1) : "ERROR: Only Markdown(*.md) supported";
  98. RendererForm.PutMarkdown(mdText);
  99. }
  100. public static void UpdateScroll()
  101. {
  102. var scrollInfo = CurrentEditor.GetScrollInfo(Win32.ScrollInfoMask.SIF_RANGE | Win32.ScrollInfoMask.SIF_TRACKPOS | Win32.ScrollInfoMask.SIF_PAGE, Win32.ScrollInfoBar.SB_VERT);
  103. double totalRange = scrollInfo.nMax - scrollInfo.nMin + 1;
  104. double scrollRatio;
  105. // Is "Enable scrolling beyond last line" checked?
  106. if (CurrentEditor.GetEndAtLastLine() == false)
  107. {
  108. var actualThumbHeight = totalRange / (totalRange / scrollInfo.nPage - 1);
  109. var actualTrackPos = scrollInfo.nTrackPos * actualThumbHeight / scrollInfo.nPage;
  110. scrollRatio = Math.Min(1, actualTrackPos / (totalRange - actualThumbHeight));
  111. }
  112. else
  113. {
  114. scrollRatio = scrollInfo.nTrackPos / (totalRange - scrollInfo.nPage);
  115. }
  116. RendererForm.ScrollToPercent(scrollRatio);
  117. }
  118. public static void Exit()
  119. {
  120. RendererForm.Close();
  121. RendererForm.Dispose();
  122. MarkdownRendererMain.Quit();
  123. }
  124. }
  125. }