|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
#nullable disable
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Windows.Forms.Design.Behavior;
namespace System.Windows.Forms.Design;
/// <summary>
/// This internal Class is used by all TOPLEVEL ToolStripItems to show the InSitu Editor. When the ToolStripItem
/// receives the MouseDown on its Glyph it calls the "ActivateEditor" Function on this EditorManager. The
/// ActivateEditor Function checks for any existing "EDITOR" active, closes that down and now opens the new
/// editor on the "AdornerWindow". This class is also responsible for "hookingup" to the F2 Command on VS.
/// </summary>
internal class ToolStripEditorManager
{
// Local copy of BehaviorService so that we can add the InSitu Editor to the AdornerWindow.
private readonly BehaviorService _behaviorService;
// Component for this InSitu Editor... (this is a ToolStripItem) that wants to go into InSitu
private readonly IDesignerHost _designerHost;
// The current Bounds of the InSitu Editor on Adorner Window.. These are required for invalidation.
private Rectangle _lastKnownEditorBounds = Rectangle.Empty;
// The encapsulated Editor.
private ToolStripEditorControl _editor;
// Actual ToolStripEditor for the current ToolStripItem.
private ToolStripTemplateNode _editorUI;
// The Current ToolStripItem that needs to go into the InSitu Mode.
// We keep a local copy so that when a new item comes in, we can "ROLLBACK" the existing edit.
private ToolStripItem _currentItem;
// The designer for current ToolStripItem.
private ToolStripItemDesigner _itemDesigner;
public ToolStripEditorManager(IComponent comp)
{
_behaviorService = (BehaviorService)comp.Site.GetService(typeof(BehaviorService));
_designerHost = (IDesignerHost)comp.Site.GetService(typeof(IDesignerHost));
}
/// <summary>
/// Activates the editor for the given item.If there's still an editor around for the previous-edited item, it is
/// deactivated. Pass in 'null' to deactivate and remove the current editor, if any.
/// </summary>
internal void ActivateEditor(ToolStripItem item)
{
if (item == _currentItem)
{
return;
}
// Remove old editor
if (_editor is not null)
{
_behaviorService.AdornerWindowControl.Controls.Remove(_editor);
_behaviorService.Invalidate(_editor.Bounds);
_editorUI = null;
_editor = null;
_currentItem = null;
_itemDesigner.IsEditorActive = false;
// Show the previously edited glyph
if (_currentItem is not null)
{
_currentItem = null;
}
}
if (item is not null)
{
// Add new editor from the item...
_currentItem = item;
if (_designerHost is not null)
{
_itemDesigner = (ToolStripItemDesigner)_designerHost.GetDesigner(_currentItem);
}
_editorUI = _itemDesigner.Editor;
// If we got an editor, position and focus it.
if (_editorUI is not null)
{
// Hide this glyph while it's being edited
_itemDesigner.IsEditorActive = true;
_editor = new ToolStripEditorControl(_editorUI.EditorToolStrip, _editorUI.Bounds);
_behaviorService.AdornerWindowControl.Controls.Add(_editor);
_lastKnownEditorBounds = _editor.Bounds;
_editor.BringToFront();
// this is important since the ToolStripEditorControl listens to textChanged messages from TextBox.
_editorUI._ignoreFirstKeyUp = true;
// Select the Editor... Put Text and Select it ...
_editorUI.FocusEditor(_currentItem);
}
}
}
/// <summary>
/// This will remove the Command for F2.
/// </summary>
internal static void CloseManager()
{
}
/// <summary>
/// This LISTENs to the Editor Resize for resizing the InSitu edit on the Adorner Window ... CURRENTLY DISABLED.
/// </summary>
private void OnEditorResize(object sender, EventArgs e)
{
// THIS IS CURRENTLY DISABLE !!!!! TO DO !! SHOULD WE SUPPORT AUTOSIZED INSITU ?????
_behaviorService.Invalidate(_lastKnownEditorBounds);
if (_editor is not null)
{
_lastKnownEditorBounds = _editor.Bounds;
}
}
// Private Class Implemented for InSitu Editor. This class just Wraps the ToolStripEditor from the TemplateNode
// and puts it in a Panel.
private class ToolStripEditorControl : Panel
{
private readonly Control _wrappedEditor;
private Rectangle _bounds;
public ToolStripEditorControl(Control editorToolStrip, Rectangle bounds)
{
_wrappedEditor = editorToolStrip;
Bounds1 = bounds;
_wrappedEditor.Resize += OnWrappedEditorResize;
Controls.Add(editorToolStrip);
Location = new Point(bounds.X, bounds.Y);
Text = "InSituEditorWrapper";
UpdateSize();
}
public Rectangle Bounds1 { get => _bounds; set => _bounds = value; }
private void OnWrappedEditorResize(object sender, EventArgs e)
{
}
private void UpdateSize() => Size = new Size(_wrappedEditor.Size.Width, _wrappedEditor.Size.Height);
}
}
|