diff options
author | Ali Can Demiralp <ali.demiralp@qt.io> | 2024-03-19 02:37:20 +0100 |
---|---|---|
committer | Ali Can Demiralp <ali.demiralp@qt.io> | 2024-03-21 09:15:10 +0000 |
commit | 33cc98bf917289b30d634f378deddc9760bbb306 (patch) | |
tree | 05f56f7f48cb3f8c578b3a12878b206a2d9e80de | |
parent | 7eb06a46681fd708ae525a4bb889519556284bb8 (diff) |
Use VS embedded info bar to show the detach option of editors
Fixes: QTVSADDINBUG-959
Change-Id: I933819e192c60bf52d304ee418bd7f953f0e8883
Reviewed-by: Karsten Heimrich <karsten.heimrich@qt.io>
-rw-r--r-- | QtVsTools.Core/Notifications.cs | 32 | ||||
-rw-r--r-- | QtVsTools.Core/VisualStudio/InfoBarMessage.cs | 16 | ||||
-rw-r--r-- | QtVsTools.Package/Editors/Editor.cs | 60 |
3 files changed, 73 insertions, 35 deletions
diff --git a/QtVsTools.Core/Notifications.cs b/QtVsTools.Core/Notifications.cs index 9ed15063..03cddc3c 100644 --- a/QtVsTools.Core/Notifications.cs +++ b/QtVsTools.Core/Notifications.cs @@ -9,6 +9,7 @@ using System.Collections.Generic; using Microsoft.VisualStudio.Imaging; using Microsoft.VisualStudio.Imaging.Interop; using Microsoft.VisualStudio.Shell; +using Microsoft.VisualStudio.Shell.Interop; using Microsoft.Win32; namespace QtVsTools.Core @@ -236,4 +237,35 @@ namespace QtVsTools.Core private List<Hyperlink> MessageHyperlinks { get; set; } = new(); protected override Hyperlink[] Hyperlinks => MessageHyperlinks.ToArray(); } + + public class NotifyDetach : InfoBarMessage + { + private Action DetachAction { get; } + + public NotifyDetach(Action detachAction, IVsInfoBarHost host = null) : base(host) + { + DetachAction = detachAction; + } + + protected override ImageMoniker Icon => KnownMonikers.StatusInformation; + + protected override TextSpan[] Text => new TextSpan[] + { + new() { Bold = true, Text = "Qt Visual Studio Tools" }, + new TextSpacer(2), + Utils.EmDash, + new TextSpacer(2), + "This window is detachable. Click detach to launch in a separate window." + }; + + protected override Hyperlink[] Hyperlinks => new Hyperlink[] + { + new() + { + Text = "Detach", + CloseInfoBar = false, + OnClicked = DetachAction + } + }; + } } diff --git a/QtVsTools.Core/VisualStudio/InfoBarMessage.cs b/QtVsTools.Core/VisualStudio/InfoBarMessage.cs index f905c038..53ea7b66 100644 --- a/QtVsTools.Core/VisualStudio/InfoBarMessage.cs +++ b/QtVsTools.Core/VisualStudio/InfoBarMessage.cs @@ -46,9 +46,9 @@ namespace QtVsTools.VisualStudio private MessageUI UI { get; set; } - public InfoBarMessage() + public InfoBarMessage(IVsInfoBarHost host = null) { - UI = new MessageUI { Message = this }; + UI = new MessageUI(this, host); } public virtual void Show() @@ -74,6 +74,7 @@ namespace QtVsTools.VisualStudio static IVsInfoBarUIFactory Factory => StaticLazy.Get(() => Factory, VsServiceProvider.GetService<SVsInfoBarUIFactory, IVsInfoBarUIFactory>); + private IVsInfoBarHost Host { get; set; } private IVsInfoBarUIElement UIElement { get; set; } private uint eventNotificationCookie; @@ -81,6 +82,12 @@ namespace QtVsTools.VisualStudio public InfoBarMessage Message { get; set; } + public MessageUI(InfoBarMessage message, IVsInfoBarHost host = null) + { + Message = message; + Host = host; + } + public void Show() { ThreadHelper.ThrowIfNotOnUIThread(); @@ -102,7 +109,10 @@ namespace QtVsTools.VisualStudio UIElement = Factory.CreateInfoBar(model); if (UIElement != null) { UIElement.Advise(this, out eventNotificationCookie); - VsShell.InfoBarHost?.AddInfoBar(UIElement); + if (Host != null) + Host.AddInfoBar(UIElement); + else + VsShell.InfoBarHost?.AddInfoBar(UIElement); } } diff --git a/QtVsTools.Package/Editors/Editor.cs b/QtVsTools.Package/Editors/Editor.cs index ef5b7e63..3d2a5c19 100644 --- a/QtVsTools.Package/Editors/Editor.cs +++ b/QtVsTools.Package/Editors/Editor.cs @@ -186,8 +186,6 @@ namespace QtVsTools.Editors private string QtToolsPath { get; } private TableLayoutPanel EditorContainer { get; set; } - private Label EditorTitle { get; } - private LinkLabel EditorDetachButton { get; } private Panel EditorControl { get; } public override IWin32Window Window => EditorContainer; @@ -197,51 +195,29 @@ namespace QtVsTools.Editors private int EditorWindowStyleExt { get; set; } private IntPtr EditorIcon { get; set; } + private NotifyDetach NotifyDetach { get; set; } + public EditorPane(Editor editor, string qtToolsPath) { Editor = editor; QtToolsPath = qtToolsPath; - var titleBar = new FlowLayoutPanel - { - AutoSize = true, - Dock = DockStyle.Fill, - BackColor = Color.FromArgb(201, 221, 201) - }; - titleBar.Controls.Add(EditorTitle = new Label - { - Text = Editor.ExecutableName, - ForeColor = Color.FromArgb(9, 16, 43), - Font = new Font("Segoe UI", 8F, FontStyle.Bold, GraphicsUnit.Point), - AutoSize = true, - Margin = new Padding(8) - }); - titleBar.Controls.Add(EditorDetachButton = new LinkLabel - { - Text = "Detach", - Font = new Font("Segoe UI", 8F, FontStyle.Regular, GraphicsUnit.Point), - AutoSize = true, - Margin = new Padding(0, 8, 8, 8) - }); - EditorDetachButton.Click += EditorDetachButton_Click; - EditorControl = new Panel { BackColor = SystemColors.Window, Dock = DockStyle.Fill }; + EditorControl.Margin = Padding.Empty; EditorControl.Resize += EditorControl_Resize; EditorContainer = new TableLayoutPanel { ColumnCount = 1, - RowCount = 2 + RowCount = 1 }; EditorContainer.ColumnStyles.Add(new ColumnStyle()); EditorContainer.RowStyles.Add(new RowStyle()); - EditorContainer.RowStyles.Add(new RowStyle()); - EditorContainer.Controls.Add(titleBar, 0, 0); - EditorContainer.Controls.Add(EditorControl, 0, 1); + EditorContainer.Controls.Add(EditorControl, 0, 0); } protected override void Dispose(bool disposing) @@ -274,10 +250,10 @@ namespace QtVsTools.Editors Editor.OnStart(EditorProcess); CloseParentFrame(); return VSConstants.S_OK; + } else { + ShowDetachBar(); } - EditorTitle.Text = Editor.GetTitle(EditorProcess); - EditorProcess.WaitForInputIdle(); EditorProcess.EnableRaisingEvents = true; EditorProcess.Exited += EditorProcess_Exited; @@ -376,7 +352,27 @@ namespace QtVsTools.Editors } } - private void EditorDetachButton_Click(object sender, EventArgs e) + private void ShowDetachBar() + { + ThreadHelper.JoinableTaskFactory.Run(async () => + { + await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); + + if (GetService(typeof(SVsWindowFrame)) is not IVsWindowFrame parentFrame) + return; + + var result = parentFrame.GetProperty((int)__VSFPROPID7.VSFPROPID_InfoBarHost, + out var value); + if (ErrorHandler.Failed(result) || value is not IVsInfoBarHost infoBarHost) + return; + + NotifyDetach?.Close(); + NotifyDetach = new NotifyDetach(Detach, infoBarHost); + NotifyDetach.Show(); + }); + } + + public void Detach() { if (EditorProcess != null) { var editorWindow = EditorWindow; |