mattercontrol/original/MatterControl.Winforms/InspectForm.cs

550 lines
14 KiB
C#
Raw Normal View History

2022-03-22 17:26:21 -07:00
/*
Copyright (c) 2022, Lars Brubaker, John Lewin
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/
using System;
2017-09-18 10:05:04 -07:00
using System.Collections.Generic;
using System.Drawing;
2017-09-18 10:05:04 -07:00
using System.Linq;
using System.Windows.Forms;
using MatterHackers.Agg;
using MatterHackers.Agg.UI;
2017-09-24 10:36:06 -07:00
using MatterHackers.DataConverters3D;
using MatterHackers.MatterControl.PartPreviewWindow;
2017-09-18 10:05:04 -07:00
using MatterHackers.VectorMath;
namespace MatterHackers.MatterControl
{
2022-10-06 17:59:31 -07:00
using WinTreeNode = System.Windows.Forms.TreeNode;
public partial class InspectForm : WinformsSystemWindow.FormInspector
2017-09-18 10:05:04 -07:00
{
2022-10-06 17:59:31 -07:00
private WinTreeNode activeTreeNode;
2017-09-18 10:05:04 -07:00
private GuiWidget inspectedSystemWindow;
private Vector2 mousePosition;
2022-10-06 17:59:31 -07:00
private Dictionary<GuiWidget, WinTreeNode> aggTreeNodes = new Dictionary<GuiWidget, WinTreeNode>();
private Dictionary<IObject3D, WinTreeNode> sceneTreeNodes = new Dictionary<IObject3D, WinTreeNode>();
2017-09-24 10:36:06 -07:00
private InteractiveScene scene;
private View3DWidget view3DWidget;
2017-09-24 10:36:06 -07:00
public InspectForm(GuiWidget inspectedSystemWindow, InteractiveScene scene, View3DWidget view3DWidget)
2017-09-24 10:36:06 -07:00
: this(inspectedSystemWindow)
{
this.view3DWidget = view3DWidget;
2017-09-24 10:36:06 -07:00
this.scene = scene;
if (scene != null)
{
this.scene.Children.ItemsModified += Scene_ChildrenModified;
sceneTreeView.SuspendLayout();
this.AddTree(scene, null);
sceneTreeView.ResumeLayout();
}
2017-09-25 07:01:01 -07:00
}
2017-09-24 10:36:06 -07:00
2017-09-25 07:01:01 -07:00
private void Scene_ChildrenModified(object sender, EventArgs e)
{
UiThread.RunOnIdle(() =>
{
sceneTreeView.SuspendLayout();
sceneTreeView.Nodes.Clear();
sceneTreeNodes.Clear();
this.AddTree(scene, null);
sceneTreeView.ResumeLayout();
});
2017-09-24 10:36:06 -07:00
}
2017-09-18 10:05:04 -07:00
public InspectForm(GuiWidget inspectedSystemWindow)
2017-09-18 10:05:04 -07:00
{
InitializeComponent();
this.inspectedSystemWindow = inspectedSystemWindow;
// Store position on move, invalidate in needed
inspectedSystemWindow.MouseMove += systemWindow_MouseMove;
inspectedSystemWindow.AfterDraw += systemWindow_AfterDraw;
inspectedSystemWindow.Invalidate();
2017-09-24 10:36:06 -07:00
aggTreeView.SuspendLayout();
this.AddTree(inspectedSystemWindow, null);
2017-09-24 10:36:06 -07:00
aggTreeView.ResumeLayout();
this.TopMost = true;
}
2017-09-18 10:05:04 -07:00
protected override bool ShowWithoutActivation => true;
2017-09-18 10:05:04 -07:00
2017-09-24 10:36:06 -07:00
private HashSet<GuiWidget> aggAncestryTree = new HashSet<GuiWidget>();
//private HashSet<IObject3D> sceneAncestryTree = new HashSet<IObject3D>();
private GuiWidget _inspectedWidget;
private GuiWidget InspectedWidget
{
get => _inspectedWidget;
set
{
if (_inspectedWidget == value)
{
return;
}
if (_inspectedWidget != null)
{
_inspectedWidget.DebugShowBounds = false;
}
_inspectedWidget = value;
this.Text = "Inspector" + (string.IsNullOrEmpty(_inspectedWidget?.Name) ? "" : " - " + _inspectedWidget.Name);
if (_inspectedWidget != null)
{
2017-09-24 10:36:06 -07:00
aggAncestryTree = new HashSet<GuiWidget>(_inspectedWidget.Parents<GuiWidget>());
aggAncestryTree.Add(_inspectedWidget);
propertyGrid1.SelectedObject = _inspectedWidget;
_inspectedWidget.DebugShowBounds = true;
var context = _inspectedWidget;
while(!context.CanSelect && context.Parent != null)
{
context = context.Parent;
}
}
if (activeTreeNode != null)
{
activeTreeNode.Checked = false;
}
2022-10-06 17:59:31 -07:00
if (aggTreeNodes.TryGetValue(_inspectedWidget, out WinTreeNode treeNode))
{
2017-09-24 10:36:06 -07:00
aggTreeView.SelectedNode = treeNode;
treeNode.EnsureVisible();
activeTreeNode = treeNode;
2017-09-24 10:36:06 -07:00
aggTreeView.Invalidate();
}
2018-01-20 10:15:47 -08:00
else
{
this.AddItemEnsureAncestors(_inspectedWidget);
}
_inspectedWidget.Invalidate();
}
}
2018-09-05 17:32:59 -07:00
2017-09-24 10:36:06 -07:00
private IObject3D _inspectedObject3D = null;
public IObject3D InspectedObject3D
{
get => _inspectedObject3D;
set
{
if (_inspectedObject3D != value)
{
_inspectedObject3D = value;
if (_inspectedObject3D != null)
{
propertyGrid1.SelectedObject = _inspectedObject3D;
//sceneAncestryTree = new HashSet<IObject3D>();
}
}
}
}
2022-10-06 17:59:31 -07:00
private void AddItemEnsureAncestors(GuiWidget widget, string text = null, WinTreeNode childNode = null, bool showAllParents = true)
2017-09-18 10:05:04 -07:00
{
if (text == null)
{
text = BuildDefaultName(widget);
}
2022-10-06 17:59:31 -07:00
if (aggTreeNodes.TryGetValue(widget, out WinTreeNode existingNode))
2017-09-18 10:05:04 -07:00
{
if (childNode != null)
{
existingNode.Nodes.Add(childNode);
}
2017-09-18 10:05:04 -07:00
existingNode.Expand();
}
else
{
2022-10-06 17:59:31 -07:00
var node = new WinTreeNode(text)
2017-09-18 10:05:04 -07:00
{
Tag = widget
};
if (childNode != null)
{
node.Nodes.Add(childNode);
node.Expand();
}
2017-09-24 10:36:06 -07:00
aggTreeNodes.Add(widget, node);
2017-09-18 10:05:04 -07:00
if (showAllParents)
2017-09-18 10:05:04 -07:00
{
var parent = widget.Parent;
if (parent == null)
{
2017-09-24 10:36:06 -07:00
aggTreeView.Nodes.Add(node);
}
else
{
2018-01-20 10:15:47 -08:00
AddItemEnsureAncestors(parent, null, node);
}
2017-09-18 10:05:04 -07:00
}
else
{
2017-09-24 10:36:06 -07:00
aggTreeView.Nodes.Add(node);
2017-09-18 10:05:04 -07:00
}
}
}
2022-10-06 17:59:31 -07:00
private WinTreeNode AddItem(GuiWidget widget, WinTreeNode parentNode)
2017-09-18 10:05:04 -07:00
{
2022-10-06 17:59:31 -07:00
var node = new WinTreeNode(BuildDefaultName(widget))
{
Tag = widget
};
2017-09-24 10:36:06 -07:00
aggTreeNodes.Add(widget, node);
2017-09-18 10:05:04 -07:00
if (parentNode == null)
2017-09-18 10:05:04 -07:00
{
2017-09-24 10:36:06 -07:00
aggTreeView.Nodes.Add(node);
}
else
{
parentNode.Nodes.Add(node);
}
2017-09-25 07:01:01 -07:00
node.Expand();
2017-09-24 10:36:06 -07:00
return node;
}
2022-10-06 17:59:31 -07:00
private WinTreeNode AddItem(IObject3D item, WinTreeNode parentNode)
2017-09-24 10:36:06 -07:00
{
2022-10-06 17:59:31 -07:00
var node = new WinTreeNode(BuildDefaultName(item))
2017-09-24 10:36:06 -07:00
{
Tag = item
};
sceneTreeNodes.Add(item, node);
if (parentNode == null)
{
sceneTreeView.Nodes.Add(node);
2017-09-25 07:01:01 -07:00
node.Expand();
}
else
{
parentNode.Nodes.Add(node);
2017-09-25 07:01:01 -07:00
parentNode.Expand();
2017-09-18 10:05:04 -07:00
}
return node;
}
2022-10-06 17:59:31 -07:00
private void AddTree(GuiWidget widget, WinTreeNode parent)
{
var node = AddItem(widget, parent);
foreach(var child in widget.Children)
{
AddTree(child, node);
}
2017-09-18 10:05:04 -07:00
}
2022-10-06 17:59:31 -07:00
private void AddTree(IObject3D item, WinTreeNode parent)
2017-09-24 10:36:06 -07:00
{
var node = AddItem(item, parent);
foreach (var child in item.Children)
{
AddTree(child, node);
}
}
private string BuildDefaultName(GuiWidget widget)
2017-09-18 10:05:04 -07:00
{
2017-10-31 13:53:27 -07:00
var type = widget.GetType();
string baseType = type == typeof(GuiWidget) || type.BaseType == typeof(GuiWidget) ? "" : $":{type.BaseType.Name}";
string controlName = string.IsNullOrEmpty(widget.Name) ? "" : $" - '{widget.Name}'";
2017-09-18 10:05:04 -07:00
2017-10-31 13:53:27 -07:00
return $"{type.Name}{baseType}{controlName}";
2017-09-18 10:05:04 -07:00
}
2017-09-24 10:36:06 -07:00
private string BuildDefaultName(IObject3D item)
{
string nameToWrite = "";
if (!string.IsNullOrEmpty(item.Name))
{
nameToWrite += $"{item.GetType().Name} - {item.Name}";
}
else
{
nameToWrite += $"{item.GetType().Name}";
}
return nameToWrite;
}
private void AggTreeView_AfterSelect(object sender, TreeViewEventArgs e)
2017-09-18 10:05:04 -07:00
{
this.InspectedWidget = e.Node.Tag as GuiWidget;
}
2019-10-22 17:42:26 -07:00
private void DebugMenus_CheckedChanged(object sender, EventArgs e)
{
PopupWidget.DebugKeepOpen = debugMenus.Checked;
ToolTipManager.DebugKeepOpen = debugMenus.Checked;
2019-10-22 17:42:26 -07:00
}
2017-09-24 10:36:06 -07:00
private void SceneTreeView_AfterSelect(object sender, TreeViewEventArgs e)
{
this.InspectedObject3D = e.Node.Tag as IObject3D;
this.scene.DebugItem = this.InspectedObject3D;
var selector = string.Join(".", this.InspectedObject3D.AncestorsAndSelf().Select(o => $"Children<{o.GetType().Name.ToString()}>").Reverse().ToArray());
Console.WriteLine(selector);
view3DWidget.Invalidate();
2017-09-24 10:36:06 -07:00
}
private void propertyGrid1_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
{
this.InspectedWidget?.Invalidate();
}
public void MoveUpTree()
{
2022-10-06 17:59:31 -07:00
if (activeTreeNode?.Parent is WinTreeNode parent)
{
this.InspectedWidget = parent.Tag as GuiWidget;
}
}
public void MoveDownTree()
{
2022-10-06 17:59:31 -07:00
if (activeTreeNode?.Nodes.Cast<WinTreeNode>().FirstOrDefault() is WinTreeNode firstChild)
{
this.InspectedWidget = firstChild.Tag as GuiWidget;
}
}
private void systemWindow_MouseMove(object sender, Agg.UI.MouseEventArgs e)
{
mousePosition = e.Position;
if (this.InspectedWidget?.FirstWidgetUnderMouse == false)
{
this.inspectedSystemWindow.Invalidate();
}
}
private void systemWindow_AfterDraw(object sender, EventArgs e)
{
2018-10-13 17:58:54 -07:00
if (this.Inspecting
&& !inspectedSystemWindow.HasBeenClosed
&& tabControl1.SelectedIndex == 0)
{
var namedChildren = new List<GuiWidget.WidgetAndPosition>();
inspectedSystemWindow.FindDescendants(
2018-12-30 08:17:01 -08:00
new[] { "" },
namedChildren,
new RectangleDouble(mousePosition.X, mousePosition.Y, mousePosition.X + 1, mousePosition.Y + 1),
GuiWidget.SearchType.Partial,
allowDisabledOrHidden: false);
// If the context changed, update the UI
if (namedChildren.LastOrDefault()?.Widget is GuiWidget firstUnderMouse
&& firstUnderMouse != this.InspectedWidget)
{
this.InspectedWidget = firstUnderMouse;
}
}
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
inspectedSystemWindow.AfterDraw -= systemWindow_AfterDraw;
inspectedSystemWindow.MouseMove -= systemWindow_MouseMove;
2017-09-25 07:01:01 -07:00
if (scene != null)
{
2017-10-02 10:49:44 -07:00
scene.Children.ItemsModified -= Scene_ChildrenModified;
scene.DebugItem = null;
2017-09-25 07:01:01 -07:00
}
base.OnFormClosing(e);
}
2017-09-24 10:36:06 -07:00
private void AggTreeView_DrawNode(object sender, DrawTreeNodeEventArgs e)
{
var node = e.Node;
if (node.IsVisible)
{
var widget = node.Tag as GuiWidget;
Brush brush;
if (node == activeTreeNode)
{
brush = SystemBrushes.Highlight;
}
2017-09-24 10:36:06 -07:00
else if (aggAncestryTree.Contains(widget))
{
brush = Brushes.LightBlue;
}
else
{
brush = Brushes.Transparent;
}
e.Graphics.FillRectangle(brush, e.Node.Bounds);
TextRenderer.DrawText(
e.Graphics,
node.Text,
2018-01-20 10:15:47 -08:00
node.NodeFont,
new Point(node.Bounds.Left, node.Bounds.Top),
widget.ActuallyVisibleOnScreen() ? SystemColors.ControlText : SystemColors.GrayText,
2017-10-31 11:43:25 -07:00
System.Drawing.Color.Transparent);
}
}
2017-09-24 10:36:06 -07:00
private void SceneTreeView_DrawNode(object sender, DrawTreeNodeEventArgs e)
{
var node = e.Node;
if (node.IsVisible)
{
//var item = node.Tag as IObject3D;
e.Graphics.FillRectangle(
2018-10-13 17:58:54 -07:00
(sceneTreeView.SelectedNode == node) ? SystemBrushes.Highlight : Brushes.Transparent,
node.Bounds);
2017-09-24 10:36:06 -07:00
TextRenderer.DrawText(
e.Graphics,
node.Text,
2018-01-20 10:15:47 -08:00
node.NodeFont,
2017-09-24 10:36:06 -07:00
new Point(node.Bounds.Left, node.Bounds.Top),
SystemColors.ControlText,
2017-10-31 11:43:25 -07:00
System.Drawing.Color.Transparent);
2017-09-24 10:36:06 -07:00
}
}
private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
{
if (this.activeTreeNode != null
&& tabControl1.SelectedIndex != 0
&& this.activeTreeNode.Tag is GuiWidget widget)
{
widget.DebugShowBounds = false;
}
if (scene != null
&& scene.DebugItem != null
&& tabControl1.SelectedIndex != 1)
{
scene.DebugItem = null;
}
2018-10-13 17:58:54 -07:00
}
private void debugTextWidget_CheckedChanged(object sender, EventArgs e)
{
TextWidget.DebugShowSize = debugTextWidget.Checked;
foreach(var widget in this.inspectedSystemWindow.Descendants<TextWidget>())
{
widget.Invalidate();
}
}
2018-01-20 10:15:47 -08:00
protected override void OnKeyUp(System.Windows.Forms.KeyEventArgs e)
{
2018-05-22 06:21:35 -07:00
if (e.KeyCode == System.Windows.Forms.Keys.F12)
2018-01-20 10:15:47 -08:00
{
this.Inspecting = !this.Inspecting;
}
2018-09-05 17:32:59 -07:00
2018-01-20 10:15:47 -08:00
base.OnKeyUp(e);
}
2018-10-13 17:58:54 -07:00
private void InspectForm_Load(object sender, EventArgs e1)
{
2022-10-06 17:59:31 -07:00
var rootNode = new WinTreeNode("Theme");
2018-10-13 17:58:54 -07:00
2022-10-06 17:59:31 -07:00
var themeNode = new WinTreeNode("Theme");
2018-10-13 17:58:54 -07:00
2022-10-06 17:59:31 -07:00
var menuThemeNode = new WinTreeNode("MenuTheme");
2018-10-13 17:58:54 -07:00
rootNode.Nodes.Add(themeNode);
rootNode.Nodes.Add(menuThemeNode);
themeTreeView.Nodes.Add(rootNode);
rootNode.Expand();
themeTreeView.AfterSelect += (s, e) =>
{
if (e.Node == rootNode)
{
propertyGrid1.SelectedObject = MatterControl.AppContext.ThemeSet;
}
else if (e.Node == themeNode)
{
propertyGrid1.SelectedObject = MatterControl.AppContext.Theme;
}
else if (e.Node == menuThemeNode)
{
propertyGrid1.SelectedObject = MatterControl.AppContext.MenuTheme;
}
};
}
private void btnApply_Click(object sender, EventArgs e)
{
ApplicationController.Instance.ReloadAll().ConfigureAwait(false);
2018-10-13 17:58:54 -07:00
}
private void button1_Click(object sender, EventArgs e)
{
var context = ApplicationController.Instance.ActivePrinters.First().Connection.TotalGCodeStream;
textBox1.Text = context.GetDebugState();
}
2017-09-18 10:05:04 -07:00
}
}