aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAli Can Demiralp <ali.demiralp@qt.io>2024-03-19 02:37:20 +0100
committerAli Can Demiralp <ali.demiralp@qt.io>2024-03-21 09:15:10 +0000
commit33cc98bf917289b30d634f378deddc9760bbb306 (patch)
tree05f56f7f48cb3f8c578b3a12878b206a2d9e80de
parent7eb06a46681fd708ae525a4bb889519556284bb8 (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.cs32
-rw-r--r--QtVsTools.Core/VisualStudio/InfoBarMessage.cs16
-rw-r--r--QtVsTools.Package/Editors/Editor.cs60
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;