Больше измнений
This commit is contained in:
@@ -0,0 +1,49 @@
|
|||||||
|
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||||
|
<s:Boolean x:Key="/Default/CodeEditing/Intellisense/CodeCompletion/IntelliSenseCompletingCharacters/CSharpCompletingCharacters/UpgradedFromVSSettings/@EntryValue">True</s:Boolean>
|
||||||
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertClosureToMethodGroup/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EntityFramework_002ENPlusOne_002EIncompleteDataQuery/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ForeachCanBeConvertedToQueryUsingAnotherGetEnumerator/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=MemberCanBeMadeStatic_002EGlobal/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=MemberCanBeMadeStatic_002ELocal/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=MemberCanBePrivate_002ELocal/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=MemberCanBeProtected_002EGlobal/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=PossibleMultipleEnumeration/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=PropertyCanBeMadeInitOnly_002EGlobal/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/OBJECT_CREATION_WHEN_TYPE_NOT_EVIDENT/@EntryValue">TargetTyped</s:String>
|
||||||
|
<s:Boolean x:Key="/Default/CodeStyle/Naming/CSharpAutoNaming/IsNotificationDisabled/@EntryValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/Dpa/IsIssuesNotificationEnabled/@EntryValue">False</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/Environment/Feedback/ShouldPrompt/@EntryValue">False</s:Boolean>
|
||||||
|
<s:Int64 x:Key="/Default/Environment/Hierarchy/GeneratedFilesCacheKey/Timestamp/@EntryValue">137</s:Int64>
|
||||||
|
<s:Boolean x:Key="/Default/Environment/InjectedLayers/FileInjectedLayer/=C9B9F1B408F26047AF920A37DEB31C9E/@KeyIndexDefined">True</s:Boolean>
|
||||||
|
<s:String x:Key="/Default/Environment/InjectedLayers/FileInjectedLayer/=C9B9F1B408F26047AF920A37DEB31C9E/AbsolutePath/@EntryValue">E:\proj\pf2e\Pf2eDataScrapper\Pf2eDataScrapper.sln.DotSettings</s:String>
|
||||||
|
<s:String x:Key="/Default/Environment/InjectedLayers/FileInjectedLayer/=C9B9F1B408F26047AF920A37DEB31C9E/RelativePath/@EntryValue"></s:String>
|
||||||
|
<s:Boolean x:Key="/Default/Environment/InjectedLayers/InjectedLayerCustomization/=FileC9B9F1B408F26047AF920A37DEB31C9E/@KeyIndexDefined">True</s:Boolean>
|
||||||
|
<s:Double x:Key="/Default/Environment/InjectedLayers/InjectedLayerCustomization/=FileC9B9F1B408F26047AF920A37DEB31C9E/RelativePriority/@EntryValue">1</s:Double>
|
||||||
|
<s:Boolean x:Key="/Default/Environment/IntraTextAdornment/VsIntraTextAdornment/ShowVsParameterNameHintsDisableNotification/@EntryValue">False</s:Boolean>
|
||||||
|
<s:Int64 x:Key="/Default/Environment/SearchAndNavigation/DefaultOccurrencesGroupingIndices/=JetBrains_002EPsiFeatures_002EUIInteractive_002ERefactorings_002EControls_002EUsagesDescriptor/@EntryIndexedValue">12</s:Int64>
|
||||||
|
<s:String x:Key="/Default/Environment/UpdatesManger/DismissedProductAndVersions/=dotCover_005F2025_002E1/@EntryIndexedValue">dotCover_2025.1</s:String>
|
||||||
|
<s:String x:Key="/Default/Environment/UpdatesManger/DismissedProductAndVersions/=ReSharper_005F2025_002E1/@EntryIndexedValue">ReSharper_2025.1</s:String>
|
||||||
|
<s:String x:Key="/Default/Environment/UpdatesManger/DismissedProductAndVersions/=ReSharperAI_005F2025_002E1/@EntryIndexedValue">ReSharperAI_2025.1</s:String>
|
||||||
|
<s:String x:Key="/Default/Environment/UpdatesManger/LastUpdateCheck/@EntryValue">05/05/2025 08:54:55</s:String>
|
||||||
|
<s:String x:Key="/Default/Environment/UpdatesManger/LastUpdateCheckPerHost/=ReSharperPlatformVs17/@EntryIndexedValue">05/02/2025 05:43:20</s:String>
|
||||||
|
<s:String x:Key="/Default/Housekeeping/AIFeatureSuggester/LastAttemptToShowFeatureSuggesterTime/@EntryValue">04/26/2025 06:45:16</s:String>
|
||||||
|
<s:String x:Key="/Default/Housekeeping/DiskCleanup/LastRunTime/@EntryValue">05/05/2025 08:58:37</s:String>
|
||||||
|
<s:Boolean x:Key="/Default/Housekeeping/FeatureSuggestion/FeatureSuggestionManager/DisabledSuggesters/=AutoNamingFeatureSuggester/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/Housekeeping/FeatureSuggestion/FeatureSuggestionManager/DisabledSuggesters/=EditorConfigFeatureSuggester/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/Housekeeping/FeatureSuggestion/FeatureSuggestionManager/DisabledSuggesters/=NullabilityAnnotationAssistSuggester/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/Housekeeping/FeatureSuggestion/FeatureSuggestionManager/DisabledSuggesters/=ShowContextActionsSuggester/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/Housekeeping/FeatureSuggestion/FeatureSuggestionManager/DisabledSuggesters/=TabNavigationExplainer/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/Housekeeping/GlobalSettingsUpgraded/IsUpgraded/@EntryValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/Housekeeping/IntellisenseHousekeeping/HintUsed/@EntryValue">True</s:Boolean>
|
||||||
|
<s:String x:Key="/Default/Housekeeping/Layout/DialogWindows/OptionsDialogView/Position/@EntryValue">[-407,3](1107,1026)</s:String>
|
||||||
|
<s:String x:Key="/Default/Housekeeping/Layout/DialogWindows/RefactoringWizardWindow/Location/@EntryValue">0,-126</s:String>
|
||||||
|
<s:Double x:Key="/Default/Housekeeping/Layout/DialogWindows/RegularExpressionEditorWindow/InputColumnWidth/@EntryValue">422</s:Double>
|
||||||
|
<s:Double x:Key="/Default/Housekeeping/Layout/DialogWindows/RegularExpressionEditorWindow/InputRowHeight/@EntryValue">268.5</s:Double>
|
||||||
|
<s:Double x:Key="/Default/Housekeeping/Layout/DialogWindows/RegularExpressionEditorWindow/MatchColumnWidth/@EntryValue">211</s:Double>
|
||||||
|
<s:Double x:Key="/Default/Housekeeping/Layout/DialogWindows/RegularExpressionEditorWindow/PatternRowHeight/@EntryValue">89.5</s:Double>
|
||||||
|
<s:Boolean x:Key="/Default/Housekeeping/LiveTemplatesHousekeeping/HotspotSessionHintIsShown/@EntryValue">True</s:Boolean>
|
||||||
|
<s:String x:Key="/Default/Housekeeping/OptionsDialog/SelectedPageId/@EntryValue">CodeInspectionSettings</s:String>
|
||||||
|
<s:Boolean x:Key="/Default/Housekeeping/UpgradeFromExceptionReport/DefaultReporterBehaviorChanged/@EntryValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/Housekeeping/UpgradeFromExceptionReport/UpgradePerformed/@EntryValue">True</s:Boolean>
|
||||||
|
<s:String x:Key="/Default/Housekeeping/WhatsNewShown/WhatsNewShownIndexedEntry/=RC/@EntryIndexedValue">2025.1.0.0</s:String>
|
||||||
|
<s:String x:Key="/Default/Housekeeping/WhatsNewShown/WhatsNewShownIndexedEntry/=RS0/@EntryIndexedValue">2025.1.0.0</s:String></wpf:ResourceDictionary>
|
||||||
+10
-5
@@ -28,28 +28,33 @@ sealed partial class EntityTreeViewerControl
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void InitializeComponent()
|
private void InitializeComponent()
|
||||||
{
|
{
|
||||||
ContentPanel = new Panel();
|
ContentPanel = new PictureBox();
|
||||||
|
((System.ComponentModel.ISupportInitialize)ContentPanel).BeginInit();
|
||||||
SuspendLayout();
|
SuspendLayout();
|
||||||
//
|
//
|
||||||
// ContentPanel
|
// ContentPanel
|
||||||
//
|
//
|
||||||
ContentPanel.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
|
|
||||||
ContentPanel.Location = new Point(0, 0);
|
ContentPanel.Location = new Point(0, 0);
|
||||||
ContentPanel.Name = "ContentPanel";
|
ContentPanel.Name = "ContentPanel";
|
||||||
ContentPanel.Size = new Size(400, 500);
|
ContentPanel.Size = new Size(400, 500);
|
||||||
ContentPanel.TabIndex = 2;
|
ContentPanel.TabIndex = 0;
|
||||||
ContentPanel.Resize += ContentPanel_Resize;
|
ContentPanel.TabStop = false;
|
||||||
|
ContentPanel.MouseMove += ContentPanel_MouseMove;
|
||||||
//
|
//
|
||||||
// EntityTreeViewerControl
|
// EntityTreeViewerControl
|
||||||
//
|
//
|
||||||
AutoScaleDimensions = new SizeF(7F, 15F);
|
AutoScaleDimensions = new SizeF(7F, 15F);
|
||||||
AutoScaleMode = AutoScaleMode.Font;
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
|
AutoScroll = true;
|
||||||
Controls.Add(ContentPanel);
|
Controls.Add(ContentPanel);
|
||||||
Name = "EntityTreeViewerControl";
|
Name = "EntityTreeViewerControl";
|
||||||
Size = new Size(400, 500);
|
Size = new Size(400, 500);
|
||||||
|
Resize += EntityTreeViewerControl_Resize;
|
||||||
|
((System.ComponentModel.ISupportInitialize)ContentPanel).EndInit();
|
||||||
ResumeLayout(false);
|
ResumeLayout(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
public Panel ContentPanel;
|
|
||||||
|
public PictureBox ContentPanel;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,13 @@
|
|||||||
using System.Collections.Generic;
|
using System.ComponentModel;
|
||||||
using System.ComponentModel;
|
using System.Diagnostics;
|
||||||
using Pf2eViewer.EntityTreeViewer;
|
|
||||||
|
|
||||||
namespace Pf2eViewer.EntityTreeViewer;
|
namespace Pf2eViewer.EntityTreeViewer;
|
||||||
|
|
||||||
public sealed partial class EntityTreeViewerControl : UserControl
|
public sealed partial class EntityTreeViewerControl : UserControl
|
||||||
{
|
{
|
||||||
private int _itemHeight = 20;
|
|
||||||
|
|
||||||
private EntityView? _entityView;
|
|
||||||
|
|
||||||
private int _depthSize = 20;
|
|
||||||
|
|
||||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
|
||||||
|
[Category("Entity Render")]
|
||||||
|
[Description("The height of each item in the tree view.")]
|
||||||
public int ItemHeight
|
public int ItemHeight
|
||||||
{
|
{
|
||||||
get => _itemHeight;
|
get => _itemHeight;
|
||||||
@@ -22,8 +17,11 @@ public sealed partial class EntityTreeViewerControl : UserControl
|
|||||||
UpdateView();
|
UpdateView();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private int _itemHeight = 20;
|
||||||
|
|
||||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||||
|
[Browsable(false)]
|
||||||
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||||
public EntityView? EntityView
|
public EntityView? EntityView
|
||||||
{
|
{
|
||||||
get => _entityView;
|
get => _entityView;
|
||||||
@@ -33,8 +31,11 @@ public sealed partial class EntityTreeViewerControl : UserControl
|
|||||||
UpdateData();
|
UpdateData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private EntityView? _entityView;
|
||||||
|
|
||||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
|
||||||
|
[Category("Entity Render")]
|
||||||
|
[Description("The size of tab.")]
|
||||||
public int DepthSize
|
public int DepthSize
|
||||||
{
|
{
|
||||||
get => _depthSize;
|
get => _depthSize;
|
||||||
@@ -44,35 +45,76 @@ public sealed partial class EntityTreeViewerControl : UserControl
|
|||||||
UpdateView();
|
UpdateView();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private int _depthSize = 20;
|
||||||
|
|
||||||
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
|
||||||
|
[Category("Entity Render")]
|
||||||
|
[Description("The size of plus/minus button.")]
|
||||||
|
public int ButtonSize
|
||||||
|
{
|
||||||
|
get => _buttonSize;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_buttonSize = value;
|
||||||
|
UpdateView();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private int _buttonSize = 20;
|
||||||
|
|
||||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||||
|
[Browsable(false)]
|
||||||
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||||
public int NameWidth { get; private set; } = 200;
|
public int NameWidth { get; private set; } = 200;
|
||||||
|
|
||||||
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
|
||||||
|
[Category("Entity Render")]
|
||||||
|
[Description("Color on item hover.")]
|
||||||
|
public Color HoverColor
|
||||||
|
{
|
||||||
|
get => _hoverColor;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_hoverColor = value;
|
||||||
|
UpdateView();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private Color _hoverColor = SystemColors.ControlDark;
|
||||||
|
|
||||||
|
[Browsable(false)]
|
||||||
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||||
|
public int ContentWidth => Width - SystemInformation.VerticalScrollBarWidth - 2;
|
||||||
|
|
||||||
private readonly List<StructureField> _rows = [];
|
private readonly List<StructureField> _rows = [];
|
||||||
|
|
||||||
private List<EntityTreeViewerRow> _viewerRows = [];
|
private List<EntityTreeViewerControlRow> _viewerRows = [];
|
||||||
|
|
||||||
|
private bool _rendering;
|
||||||
|
|
||||||
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||||
|
[Browsable(false)]
|
||||||
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||||
|
public Bitmap ContentImage { get; set; }
|
||||||
|
|
||||||
public EntityTreeViewerControl()
|
public EntityTreeViewerControl()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
ContentImage = new(ContentWidth, Height);
|
||||||
DoubleBuffered = true;
|
DoubleBuffered = true;
|
||||||
|
VerticalScroll.Visible = true;
|
||||||
|
HorizontalScroll.Visible = false;
|
||||||
|
|
||||||
ContentPanel.AutoScroll = false;
|
ContentPanel.MouseWheel += ContentPanel_MouseWheel;
|
||||||
ContentPanel.HorizontalScroll.Maximum = 0;
|
|
||||||
ContentPanel.HorizontalScroll.Visible = false;
|
|
||||||
ContentPanel.AutoScroll = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateData()
|
public void UpdateData()
|
||||||
{
|
{
|
||||||
ContentPanel.Controls.Clear();
|
|
||||||
|
|
||||||
if (EntityView?.Entity is null)
|
if (EntityView?.Entity is null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_rows.Clear();
|
_rows.Clear();
|
||||||
|
ContentPanel.Controls.Clear();
|
||||||
|
|
||||||
StructureBuilder builder = new();
|
StructureBuilder builder = new();
|
||||||
|
|
||||||
@@ -85,57 +127,75 @@ public sealed partial class EntityTreeViewerControl : UserControl
|
|||||||
_rows.Add(builder.Create(typeName, EntityView.SubEntity));
|
_rows.Add(builder.Create(typeName, EntityView.SubEntity));
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateRows();
|
_viewerRows = _rows
|
||||||
UpdateView();
|
.SelectMany(r => r.GetRows(row => new EntityTreeViewerControlRow(this, row)))
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
UpdateRenders();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateRows()
|
public void UpdateRenders()
|
||||||
{
|
{
|
||||||
_viewerRows = _rows.SelectMany(r => r.GetTextRows(this)).ToList();
|
int maxNameWidth = -1;
|
||||||
|
|
||||||
ContentPanel.Controls.Clear();
|
foreach (EntityTreeViewerControlRow row in _viewerRows)
|
||||||
ContentPanel.Controls.AddRange(_viewerRows.ToArray<Control>());
|
{
|
||||||
|
int nameWidth = row.NameWidth + row.Item.Depth * DepthSize;
|
||||||
|
maxNameWidth = Math.Max(maxNameWidth, nameWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
NameWidth = maxNameWidth + 3;
|
||||||
|
|
||||||
|
Debug.WriteLine($@"Height Inner {ContentWidth} / Outer {Width}");
|
||||||
|
Debug.WriteLine($@"Name {NameWidth} / Full {ContentWidth}");
|
||||||
|
|
||||||
|
foreach (EntityTreeViewerControlRow row in _viewerRows)
|
||||||
|
{
|
||||||
|
row.UpdateCache();
|
||||||
|
}
|
||||||
|
|
||||||
UpdateView();
|
UpdateView();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateView()
|
public void UpdateView()
|
||||||
{
|
{
|
||||||
foreach (EntityTreeViewerRow row in _viewerRows)
|
_viewerRows.ForEach(row => row.UpdateButton());
|
||||||
|
|
||||||
|
List<EntityTreeViewerControlRow> rows = _viewerRows.Where(r => r.Item.Visible).ToList();
|
||||||
|
if (rows.Count == 0)
|
||||||
{
|
{
|
||||||
row.Visible = row.Item.Visible;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<EntityTreeViewerRow> rows = _viewerRows.Where(r => r.Item.Visible).ToList();
|
|
||||||
|
|
||||||
int maxNameWidth = -1;
|
|
||||||
int viewRow = 0;
|
|
||||||
|
|
||||||
foreach (EntityTreeViewerRow row in rows)
|
|
||||||
{
|
|
||||||
row.ViewIndex = viewRow++;
|
|
||||||
int nameWidth = row.NameWidth + row.Item.Depth * DepthSize;
|
|
||||||
maxNameWidth = Math.Max(maxNameWidth, nameWidth);
|
|
||||||
}
|
|
||||||
|
|
||||||
NameWidth = maxNameWidth;
|
|
||||||
|
|
||||||
BuildLadder(rows);
|
BuildLadder(rows);
|
||||||
|
|
||||||
foreach (EntityTreeViewerRow row in rows)
|
_rendering = true;
|
||||||
|
ContentImage = new(ContentWidth, rows.Count * ItemHeight);
|
||||||
|
Graphics g = Graphics.FromImage(ContentImage);
|
||||||
|
|
||||||
|
int viewRow = 0;
|
||||||
|
foreach (EntityTreeViewerControlRow row in rows)
|
||||||
{
|
{
|
||||||
row.Refresh();
|
row.ViewIndex = viewRow++;
|
||||||
}
|
row.Invalidate(g);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BuildLadder(List<EntityTreeViewerRow> rows)
|
g.Save();
|
||||||
|
|
||||||
|
ContentPanel.Image = ContentImage;
|
||||||
|
ContentPanel.Width = ContentImage.Width;
|
||||||
|
ContentPanel.Height = ContentImage.Height;
|
||||||
|
|
||||||
|
_rendering = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BuildLadder(List<EntityTreeViewerControlRow> rows)
|
||||||
{
|
{
|
||||||
List<LadderType> lastLadder = [];
|
List<LadderType> lastLadder = [];
|
||||||
ContentPanel.VerticalScroll.Visible = true;
|
|
||||||
|
|
||||||
for (int i = rows.Count - 1; i >= 0; i--)
|
for (int i = rows.Count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
EntityTreeViewerRow row = rows[i];
|
EntityTreeViewerControlRow row = rows[i];
|
||||||
List<LadderType> ladder;
|
List<LadderType> ladder;
|
||||||
|
|
||||||
if (row.Depth == 0)
|
if (row.Depth == 0)
|
||||||
@@ -176,8 +236,53 @@ public sealed partial class EntityTreeViewerControl : UserControl
|
|||||||
|
|
||||||
// Events
|
// Events
|
||||||
|
|
||||||
private void ContentPanel_Resize(object sender, EventArgs e)
|
private void EntityTreeViewerControl_Resize(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
UpdateView();
|
if (_rendering)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ContentPanel.Width = Width;
|
||||||
|
|
||||||
|
UpdateRenders();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ContentPanel_MouseWheel(object? sender, MouseEventArgs e)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
int initValue = VerticalScroll.Value;
|
||||||
|
int delta = -e.Delta / 120;
|
||||||
|
|
||||||
|
VerticalScroll.Value = Math.Clamp(
|
||||||
|
initValue + delta,
|
||||||
|
VerticalScrollBar.Minimum,
|
||||||
|
VerticalScrollBar.Maximum - VerticalScrollBar.LargeChange + 1
|
||||||
|
);
|
||||||
|
|
||||||
|
if (VerticalScrollBar.Value != initValue)
|
||||||
|
{
|
||||||
|
ContentPanel.Invalidate();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ContentPanel_MouseMove(object sender, MouseEventArgs e)
|
||||||
|
{
|
||||||
|
PointF p = new(e.X, e.Y);
|
||||||
|
|
||||||
|
foreach (EntityTreeViewerControlRow row in _viewerRows)
|
||||||
|
{
|
||||||
|
bool contained = row.Target.Contains(p);
|
||||||
|
|
||||||
|
if (contained != row.Hovered)
|
||||||
|
{
|
||||||
|
Rectangle r = new();
|
||||||
|
row.RealTarget.Intersect(r);
|
||||||
|
ContentPanel.Invalidate(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
row.Hovered = contained;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,385 @@
|
|||||||
|
using FontAwesome.Sharp;
|
||||||
|
using Font = System.Drawing.Font;
|
||||||
|
using FontStyle = System.Drawing.FontStyle;
|
||||||
|
using Image = System.Drawing.Image;
|
||||||
|
|
||||||
|
namespace Pf2eViewer.EntityTreeViewer;
|
||||||
|
|
||||||
|
internal class EntityTreeViewerControlRow
|
||||||
|
{
|
||||||
|
public readonly EntityTreeViewerControl ParentControl;
|
||||||
|
|
||||||
|
public readonly StructureField Item;
|
||||||
|
|
||||||
|
// Local fields
|
||||||
|
public Image Cache
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_cache == null)
|
||||||
|
{
|
||||||
|
UpdateCache();
|
||||||
|
}
|
||||||
|
return _cache!;
|
||||||
|
}
|
||||||
|
set => _cache = value;
|
||||||
|
}
|
||||||
|
private Image? _cache;
|
||||||
|
|
||||||
|
public List<LadderType> Ladder
|
||||||
|
{
|
||||||
|
get => _ladder;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_ladder = value;
|
||||||
|
_cache = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private List<LadderType> _ladder = [];
|
||||||
|
|
||||||
|
public bool Hovered
|
||||||
|
{
|
||||||
|
get => _hovered;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != _hovered)
|
||||||
|
{
|
||||||
|
_hovered = value;
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private bool _hovered = false;
|
||||||
|
|
||||||
|
public int ViewIndex { get; set; } // = -1;
|
||||||
|
|
||||||
|
public IconButton? Button { get; set; } = null;
|
||||||
|
|
||||||
|
// Inherited fields
|
||||||
|
|
||||||
|
public Font Font
|
||||||
|
{
|
||||||
|
get => ParentControl.Font;
|
||||||
|
set => ParentControl.Font = value;
|
||||||
|
}
|
||||||
|
public Color ForeColor
|
||||||
|
{
|
||||||
|
get => ParentControl.ForeColor;
|
||||||
|
set => ParentControl.ForeColor = value;
|
||||||
|
}
|
||||||
|
public Color BackColor
|
||||||
|
{
|
||||||
|
get => ParentControl.BackColor;
|
||||||
|
set => ParentControl.BackColor = value;
|
||||||
|
}
|
||||||
|
public Color HoverColor
|
||||||
|
{
|
||||||
|
get => ParentControl.HoverColor;
|
||||||
|
set => ParentControl.HoverColor = value;
|
||||||
|
}
|
||||||
|
public int ItemHeight
|
||||||
|
{
|
||||||
|
get => ParentControl.ItemHeight;
|
||||||
|
set => ParentControl.ItemHeight = value;
|
||||||
|
}
|
||||||
|
public int DepthSize
|
||||||
|
{
|
||||||
|
get => ParentControl.DepthSize;
|
||||||
|
set => ParentControl.DepthSize = value;
|
||||||
|
}
|
||||||
|
public int ButtonSize
|
||||||
|
{
|
||||||
|
get => ParentControl.ButtonSize;
|
||||||
|
set => ParentControl.ButtonSize = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValueText functions
|
||||||
|
|
||||||
|
public int Width => ParentControl.ContentWidth;
|
||||||
|
public int Height => ItemHeight;
|
||||||
|
public bool HasButton => Item.FieldType == StructureFieldType.Complex;
|
||||||
|
public int Depth => Item.Depth;
|
||||||
|
public int NameWidth
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
Graphics g = Graphics.FromImage(Cache);
|
||||||
|
return Convert.ToInt32(g.MeasureString(Item.Name, Font).Width + DepthSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string TypeText
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
string result = Item.GetTypeString();
|
||||||
|
if (result != "")
|
||||||
|
{
|
||||||
|
result = $@"({result})";
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public Font TypeFont => new(Font.FontFamily, Font.Size * 0.6f, FontStyle.Italic);
|
||||||
|
|
||||||
|
public string ValueText => Item.GetValueString();
|
||||||
|
public Font ValueFont =>
|
||||||
|
new(
|
||||||
|
Font.FontFamily,
|
||||||
|
Font.Size,
|
||||||
|
Item.FieldType == StructureFieldType.Complex ? FontStyle.Italic : FontStyle.Regular
|
||||||
|
);
|
||||||
|
|
||||||
|
public RectangleF Target => new(0, ViewIndex * Height, Width, Height);
|
||||||
|
public RectangleF RealTarget =>
|
||||||
|
new(0, ViewIndex * Height - ParentControl.VerticalScroll.Value, Width, Height);
|
||||||
|
|
||||||
|
// Simple fields
|
||||||
|
|
||||||
|
private readonly List<StringRenderData> _renderData = [];
|
||||||
|
|
||||||
|
// Main methods
|
||||||
|
|
||||||
|
public EntityTreeViewerControlRow(EntityTreeViewerControl parent, StructureField item)
|
||||||
|
{
|
||||||
|
ParentControl = parent;
|
||||||
|
Item = item;
|
||||||
|
ApplyItem();
|
||||||
|
UpdateCache();
|
||||||
|
|
||||||
|
UpdateButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyItem()
|
||||||
|
{
|
||||||
|
_renderData.Clear();
|
||||||
|
|
||||||
|
_renderData.Add(new(Item.Name, Font, ForeColor));
|
||||||
|
_renderData.Add(new(TypeText, TypeFont, GetValueColor()));
|
||||||
|
_renderData.Add(
|
||||||
|
new(ValueText.Replace("\r", "").Replace('\n', ' '), ValueFont, GetValueColor())
|
||||||
|
);
|
||||||
|
|
||||||
|
if (HasButton)
|
||||||
|
{
|
||||||
|
Button = new()
|
||||||
|
{
|
||||||
|
Width = ButtonSize,
|
||||||
|
Height = ButtonSize,
|
||||||
|
IconSize = ButtonSize,
|
||||||
|
IconChar = IconChar.MinusSquare,
|
||||||
|
ImageAlign = ContentAlignment.MiddleCenter,
|
||||||
|
TextAlign = ContentAlignment.MiddleCenter,
|
||||||
|
Visible = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
Button.Click += Button_Click;
|
||||||
|
|
||||||
|
ParentControl.ContentPanel.Controls.Add(Button);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateCache()
|
||||||
|
{
|
||||||
|
Cache = new Bitmap(Width, Height);
|
||||||
|
Graphics g = Graphics.FromImage(Cache);
|
||||||
|
|
||||||
|
RenderLadder(g);
|
||||||
|
RenderContent(g);
|
||||||
|
|
||||||
|
g.Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Invalidate(Graphics? g = null)
|
||||||
|
{
|
||||||
|
g ??= Graphics.FromImage(ParentControl.ContentImage);
|
||||||
|
|
||||||
|
g.FillRectangle(new SolidBrush(Hovered ? HoverColor : BackColor), Target);
|
||||||
|
g.DrawImage(Cache, Target);
|
||||||
|
|
||||||
|
UpdateButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Button
|
||||||
|
|
||||||
|
public void UpdateButton()
|
||||||
|
{
|
||||||
|
if (Button is null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cx = Convert.ToInt32((0.5 + Depth) * DepthSize - 0.5 * ButtonSize);
|
||||||
|
int cy = Convert.ToInt32((0.5 + ViewIndex) * ItemHeight - 0.5 * ButtonSize);
|
||||||
|
|
||||||
|
Button.Left = cx;
|
||||||
|
Button.Top = cy;
|
||||||
|
|
||||||
|
Button!.IconChar = ((StructureFieldComplex)Item).Collapsed
|
||||||
|
? IconChar.PlusSquare
|
||||||
|
: IconChar.MinusSquare;
|
||||||
|
Button.Visible = Item.Visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Button_Click(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (Item is StructureFieldComplex complex)
|
||||||
|
{
|
||||||
|
complex.Collapsed = !complex.Collapsed;
|
||||||
|
ParentControl.UpdateView();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render
|
||||||
|
|
||||||
|
private void RenderLadder(Graphics g)
|
||||||
|
{
|
||||||
|
int n = Depth;
|
||||||
|
int h = ItemHeight;
|
||||||
|
int w = DepthSize;
|
||||||
|
|
||||||
|
if (_ladder.Count < Depth)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Pen pen = new(Color.FromArgb(127, ForeColor.R, ForeColor.G, ForeColor.B), 1);
|
||||||
|
pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
|
||||||
|
|
||||||
|
float cy = 0.5f * h;
|
||||||
|
|
||||||
|
for (int i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
float cx = (i + 1.5f) * w;
|
||||||
|
|
||||||
|
switch (_ladder[i])
|
||||||
|
{
|
||||||
|
case LadderType.Last:
|
||||||
|
g.DrawLine(pen, cx, 0, cx, cy);
|
||||||
|
break;
|
||||||
|
case LadderType.Through:
|
||||||
|
g.DrawLine(pen, cx, 0, cx, h);
|
||||||
|
break;
|
||||||
|
case LadderType.Empty:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == n - 1)
|
||||||
|
{
|
||||||
|
g.DrawLine(pen, cx, cy, (i + 2) * w, cy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RenderContent(Graphics g)
|
||||||
|
{
|
||||||
|
float[] xs =
|
||||||
|
[
|
||||||
|
DepthSize * (Item.Depth + 1),
|
||||||
|
ParentControl.NameWidth,
|
||||||
|
ParentControl.NameWidth + g.MeasureString(TypeText, TypeFont).Width + 3,
|
||||||
|
Width,
|
||||||
|
];
|
||||||
|
|
||||||
|
Pen p = new(Color.Aqua, 1);
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
StringRenderData item = _renderData[i];
|
||||||
|
|
||||||
|
item.Left = xs[i];
|
||||||
|
item.Width = xs[i + 1] - xs[i];
|
||||||
|
item.Height = ItemHeight;
|
||||||
|
|
||||||
|
// g.DrawRectangle(p, item.Rect);
|
||||||
|
item.Draw(g);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper functions
|
||||||
|
|
||||||
|
private Color BlendColor(Color color, double rate = 0.5)
|
||||||
|
{
|
||||||
|
return BlendColor(ForeColor, color, rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Color BlendColor(Color color1, Color color2, double rate)
|
||||||
|
{
|
||||||
|
return Color.FromArgb(
|
||||||
|
Mix(color1.A, color2.A),
|
||||||
|
Mix(color1.R, color2.R),
|
||||||
|
Mix(color1.G, color2.G),
|
||||||
|
Mix(color1.B, color2.B)
|
||||||
|
);
|
||||||
|
|
||||||
|
int Mix(int a, int b) => Convert.ToInt32(Math.Round(a * rate + b * (1 - rate)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color GetValueColor()
|
||||||
|
{
|
||||||
|
return Item switch
|
||||||
|
{
|
||||||
|
StructureFieldPrimitive primitive => Type.GetTypeCode(primitive.Type) switch
|
||||||
|
{
|
||||||
|
TypeCode.Boolean => BlendColor(Color.DarkGoldenrod),
|
||||||
|
TypeCode.Int32 => BlendColor(Color.Blue),
|
||||||
|
TypeCode.Double => BlendColor(Color.Aqua),
|
||||||
|
TypeCode.String => BlendColor(Color.Green),
|
||||||
|
_ => ForeColor,
|
||||||
|
},
|
||||||
|
StructureFieldEnum => BlendColor(Color.Red),
|
||||||
|
_ => ForeColor,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private class StringRenderData(string text, Font font, Color color)
|
||||||
|
{
|
||||||
|
public string Text { get; } = text;
|
||||||
|
public Font Font { get; } = font;
|
||||||
|
public Color Color { get; } = color;
|
||||||
|
|
||||||
|
public float Left { get; set; }
|
||||||
|
public float Width { get; set; }
|
||||||
|
public float Height { get; set; }
|
||||||
|
|
||||||
|
public RectangleF Rect => new(Left, 0, Width, Height);
|
||||||
|
|
||||||
|
private string Fit(Graphics g, RectangleF rect)
|
||||||
|
{
|
||||||
|
if (Text.Length == 0 || g.MeasureString(Text, Font).Width <= rect.Width)
|
||||||
|
{
|
||||||
|
return Text;
|
||||||
|
}
|
||||||
|
|
||||||
|
string txt = Text.Length > 100 ? Text[..100] : Text;
|
||||||
|
|
||||||
|
int i = txt.Length;
|
||||||
|
|
||||||
|
while (g.MeasureString(txt + "...", Font).Width > rect.Width)
|
||||||
|
{
|
||||||
|
txt = txt[..--i];
|
||||||
|
if (i == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return txt + "...";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Draw(Graphics g)
|
||||||
|
{
|
||||||
|
g.DrawString(
|
||||||
|
Fit(g, Rect),
|
||||||
|
Font,
|
||||||
|
new SolidBrush(Color),
|
||||||
|
Rect,
|
||||||
|
new StringFormat
|
||||||
|
{
|
||||||
|
Alignment = StringAlignment.Near,
|
||||||
|
LineAlignment = StringAlignment.Center,
|
||||||
|
FormatFlags = StringFormatFlags.NoWrap,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-2
@@ -91,7 +91,7 @@ sealed partial class EntityTreeViewerRow
|
|||||||
TypeLabel.Name = "TypeLabel";
|
TypeLabel.Name = "TypeLabel";
|
||||||
TypeLabel.Size = new Size(57, 38);
|
TypeLabel.Size = new Size(57, 38);
|
||||||
TypeLabel.TabIndex = 3;
|
TypeLabel.TabIndex = 3;
|
||||||
TypeLabel.Text = "Type";
|
TypeLabel.Text = "TypeText";
|
||||||
TypeLabel.TextAlign = ContentAlignment.MiddleLeft;
|
TypeLabel.TextAlign = ContentAlignment.MiddleLeft;
|
||||||
//
|
//
|
||||||
// ValueLabel
|
// ValueLabel
|
||||||
@@ -102,7 +102,7 @@ sealed partial class EntityTreeViewerRow
|
|||||||
ValueLabel.Name = "ValueLabel";
|
ValueLabel.Name = "ValueLabel";
|
||||||
ValueLabel.Size = new Size(288, 38);
|
ValueLabel.Size = new Size(288, 38);
|
||||||
ValueLabel.TabIndex = 4;
|
ValueLabel.TabIndex = 4;
|
||||||
ValueLabel.Text = "Value";
|
ValueLabel.Text = "ValueText";
|
||||||
ValueLabel.TextAlign = ContentAlignment.MiddleLeft;
|
ValueLabel.TextAlign = ContentAlignment.MiddleLeft;
|
||||||
//
|
//
|
||||||
// EntityTreeViewerRow
|
// EntityTreeViewerRow
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ internal sealed partial class EntityTreeViewerRow : UserControl
|
|||||||
set => ParentControl.ItemHeight = value;
|
set => ParentControl.ItemHeight = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Value functions
|
// ValueText functions
|
||||||
|
|
||||||
public bool HasButton => Item.FieldType == StructureFieldType.Complex;
|
public bool HasButton => Item.FieldType == StructureFieldType.Complex;
|
||||||
public int Depth => Item.Depth;
|
public int Depth => Item.Depth;
|
||||||
@@ -122,7 +122,7 @@ internal sealed partial class EntityTreeViewerRow : UserControl
|
|||||||
|
|
||||||
Left = 0;
|
Left = 0;
|
||||||
Top = ViewIndex * ParentControl.ItemHeight;
|
Top = ViewIndex * ParentControl.ItemHeight;
|
||||||
Width = ParentControl.ContentPanel.Width - Left - SystemInformation.VerticalScrollBarWidth;
|
Width = ParentControl.ContentWidth - Left - SystemInformation.VerticalScrollBarWidth;
|
||||||
Height = ParentControl.ItemHeight;
|
Height = ParentControl.ItemHeight;
|
||||||
|
|
||||||
// Name Panel
|
// Name Panel
|
||||||
@@ -135,7 +135,7 @@ internal sealed partial class EntityTreeViewerRow : UserControl
|
|||||||
NameLabel.Left = IconPictureBox.Width;
|
NameLabel.Left = IconPictureBox.Width;
|
||||||
NameLabel.Width = NamePanel.Width - NameLabel.Left;
|
NameLabel.Width = NamePanel.Width - NameLabel.Left;
|
||||||
|
|
||||||
// Value Panel
|
// ValueText Panel
|
||||||
ValuePanel.Left = NamePanel.Left + NamePanel.Width;
|
ValuePanel.Left = NamePanel.Left + NamePanel.Width;
|
||||||
ValuePanel.Width = Width - ValuePanel.Left;
|
ValuePanel.Width = Width - ValuePanel.Left;
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ internal class StructureBuilder
|
|||||||
|
|
||||||
public void CompleteProcessed(object value, StructureFieldComplex field)
|
public void CompleteProcessed(object value, StructureFieldComplex field)
|
||||||
{
|
{
|
||||||
var q = _processedObjects.FirstOrDefault(p => p.Value == value);
|
StructureProcessedObject? q = _processedObjects.FirstOrDefault(p => p.Value == value);
|
||||||
|
|
||||||
if (q == null)
|
if (q == null)
|
||||||
{
|
{
|
||||||
@@ -59,6 +59,9 @@ internal class StructureBuilder
|
|||||||
case StructureFieldType.Enum:
|
case StructureFieldType.Enum:
|
||||||
return new StructureFieldEnum(this, value!, name, depth);
|
return new StructureFieldEnum(this, value!, name, depth);
|
||||||
|
|
||||||
|
case StructureFieldType.Reference:
|
||||||
|
break;
|
||||||
|
|
||||||
case StructureFieldType.Complex:
|
case StructureFieldType.Complex:
|
||||||
default:
|
default:
|
||||||
|
|
||||||
@@ -66,15 +69,22 @@ internal class StructureBuilder
|
|||||||
p.Value == value
|
p.Value == value
|
||||||
);
|
);
|
||||||
|
|
||||||
if (processed is not null)
|
if (processed is null)
|
||||||
{
|
{
|
||||||
var reference = new StructureFieldReference(this, name, null, depth);
|
return Create(name, value!, depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
StructureFieldReference reference = new StructureFieldReference(
|
||||||
|
this,
|
||||||
|
name,
|
||||||
|
null,
|
||||||
|
depth
|
||||||
|
);
|
||||||
processed.AddReference(reference);
|
processed.AddReference(reference);
|
||||||
return reference;
|
return reference;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Create(name, value!, depth);
|
throw new("Impossible");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static StructureFieldType GetFieldType(object? value)
|
public static StructureFieldType GetFieldType(object? value)
|
||||||
@@ -112,7 +122,7 @@ internal class StructureProcessedObject(object value)
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
_field = value;
|
_field = value;
|
||||||
foreach (var reference in _references)
|
foreach (StructureFieldReference reference in _references)
|
||||||
{
|
{
|
||||||
reference.Reference = Field;
|
reference.Reference = Field;
|
||||||
}
|
}
|
||||||
@@ -158,7 +168,7 @@ internal abstract class StructureField(StructureBuilder builder, string name, in
|
|||||||
|
|
||||||
public virtual bool Visible { get; set; } = true;
|
public virtual bool Visible { get; set; } = true;
|
||||||
|
|
||||||
public int Depth = depth;
|
public readonly int Depth = depth;
|
||||||
|
|
||||||
public abstract string GetTypeString();
|
public abstract string GetTypeString();
|
||||||
|
|
||||||
@@ -166,7 +176,13 @@ internal abstract class StructureField(StructureBuilder builder, string name, in
|
|||||||
|
|
||||||
public virtual ICollection<EntityTreeViewerRow> GetTextRows(EntityTreeViewerControl control)
|
public virtual ICollection<EntityTreeViewerRow> GetTextRows(EntityTreeViewerControl control)
|
||||||
{
|
{
|
||||||
return [new EntityTreeViewerRow(control, this)];
|
return [new(control, this)];
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual ICollection<T> GetRows<T>(Func<StructureField, T> func)
|
||||||
|
{
|
||||||
|
StructureField[] q = [this];
|
||||||
|
return q.Select(func).ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,7 +205,7 @@ internal class StructureFieldPrimitive(
|
|||||||
{
|
{
|
||||||
public override StructureFieldType FieldType => StructureFieldType.Primitive;
|
public override StructureFieldType FieldType => StructureFieldType.Primitive;
|
||||||
|
|
||||||
public object Value = value;
|
public readonly object Value = value;
|
||||||
|
|
||||||
public readonly Type Type = value.GetType();
|
public readonly Type Type = value.GetType();
|
||||||
|
|
||||||
@@ -221,7 +237,7 @@ internal class StructureFieldEnum(StructureBuilder builder, object value, string
|
|||||||
{
|
{
|
||||||
public override StructureFieldType FieldType => StructureFieldType.Enum;
|
public override StructureFieldType FieldType => StructureFieldType.Enum;
|
||||||
|
|
||||||
public object Value = value;
|
public readonly object Value = value;
|
||||||
|
|
||||||
public readonly Type Type = value.GetType();
|
public readonly Type Type = value.GetType();
|
||||||
|
|
||||||
@@ -238,8 +254,6 @@ internal class StructureFieldComplex : StructureField
|
|||||||
|
|
||||||
public readonly Type Type;
|
public readonly Type Type;
|
||||||
|
|
||||||
private bool _collapsed = false;
|
|
||||||
|
|
||||||
public bool Collapsed
|
public bool Collapsed
|
||||||
{
|
{
|
||||||
get => _collapsed;
|
get => _collapsed;
|
||||||
@@ -249,16 +263,7 @@ internal class StructureFieldComplex : StructureField
|
|||||||
UpdateFieldVisibility();
|
UpdateFieldVisibility();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private bool _collapsed = false;
|
||||||
private bool _visible = true;
|
|
||||||
|
|
||||||
public StructureFieldComplex(StructureBuilder builder, object value, string name, int depth)
|
|
||||||
: base(builder, name, depth)
|
|
||||||
{
|
|
||||||
Type = value.GetType();
|
|
||||||
|
|
||||||
SetFields((dynamic)value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Visible
|
public override bool Visible
|
||||||
{
|
{
|
||||||
@@ -269,10 +274,19 @@ internal class StructureFieldComplex : StructureField
|
|||||||
UpdateFieldVisibility();
|
UpdateFieldVisibility();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private bool _visible = true;
|
||||||
|
|
||||||
|
public StructureFieldComplex(StructureBuilder builder, object value, string name, int depth)
|
||||||
|
: base(builder, name, depth)
|
||||||
|
{
|
||||||
|
Type = value.GetType();
|
||||||
|
|
||||||
|
SetFields((dynamic)value);
|
||||||
|
}
|
||||||
|
|
||||||
private void UpdateFieldVisibility()
|
private void UpdateFieldVisibility()
|
||||||
{
|
{
|
||||||
foreach (var field in Fields)
|
foreach (StructureField field in Fields)
|
||||||
{
|
{
|
||||||
field.Visible = Visible && !Collapsed;
|
field.Visible = Visible && !Collapsed;
|
||||||
}
|
}
|
||||||
@@ -280,24 +294,22 @@ internal class StructureFieldComplex : StructureField
|
|||||||
|
|
||||||
private void SetFields(LocaleString localeString)
|
private void SetFields(LocaleString localeString)
|
||||||
{
|
{
|
||||||
List<FieldRecord> records = [];
|
SetFieldsFromRecords(
|
||||||
|
localeString
|
||||||
foreach (var field in localeString)
|
.Select(field => new FieldRecord(field.Locale.ToString(), field.Value))
|
||||||
{
|
.ToList()
|
||||||
records.Add(new FieldRecord(field.Locale.ToString(), field.Value));
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
SetFieldsFromRecords(records);
|
private void SetFields(IEnumerable enumerable)
|
||||||
}
|
|
||||||
|
|
||||||
private void SetFields(IEnumerable enumrable)
|
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
List<FieldRecord> records = [];
|
List<FieldRecord> records = [];
|
||||||
|
|
||||||
foreach (var item in enumrable)
|
foreach (object? item in enumerable)
|
||||||
{
|
{
|
||||||
records.Add(new FieldRecord($"[{i++}]", item));
|
records.Add(new($"[{i++}]", item));
|
||||||
}
|
}
|
||||||
|
|
||||||
SetFieldsFromRecords(records);
|
SetFieldsFromRecords(records);
|
||||||
@@ -320,24 +332,22 @@ internal class StructureFieldComplex : StructureField
|
|||||||
|
|
||||||
private void SetFieldsFromRecords(List<FieldRecord> records)
|
private void SetFieldsFromRecords(List<FieldRecord> records)
|
||||||
{
|
{
|
||||||
foreach (FieldRecord record in records)
|
foreach (
|
||||||
{
|
FieldRecord record in records.Where(record =>
|
||||||
if (record.FieldType == StructureFieldType.Complex)
|
record.FieldType == StructureFieldType.Complex
|
||||||
|
)
|
||||||
|
)
|
||||||
{
|
{
|
||||||
record.Allowed = Builder.RegisterProcessed(record.Value!);
|
record.Allowed = Builder.RegisterProcessed(record.Value!);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var record in records)
|
foreach (FieldRecord record in records)
|
||||||
{
|
{
|
||||||
if (record.FieldType == StructureFieldType.Complex && record.Allowed)
|
Fields.Add(
|
||||||
{
|
record is { FieldType: StructureFieldType.Complex, Allowed: true }
|
||||||
Fields.Add(Builder.Create(record.Name, record.Value!, Depth + 1));
|
? Builder.Create(record.Name, record.Value!, Depth + 1)
|
||||||
}
|
: Builder.Resolve(record.Name, record.Value!, Depth + 1)
|
||||||
else
|
);
|
||||||
{
|
|
||||||
Fields.Add(Builder.Resolve(record.Name, record.Value!, Depth + 1));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -350,11 +360,16 @@ internal class StructureFieldComplex : StructureField
|
|||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override ICollection<T> GetRows<T>(Func<StructureField, T> func)
|
||||||
|
{
|
||||||
|
return [.. base.GetRows(func), .. Fields.SelectMany(f => f.GetRows(func)).ToList()];
|
||||||
|
}
|
||||||
|
|
||||||
private class FieldRecord(string name, object? value)
|
private class FieldRecord(string name, object? value)
|
||||||
{
|
{
|
||||||
public string Name = name;
|
public readonly string Name = name;
|
||||||
|
|
||||||
public object? Value = value;
|
public readonly object? Value = value;
|
||||||
|
|
||||||
public StructureFieldType FieldType => StructureBuilder.GetFieldType(Value);
|
public StructureFieldType FieldType => StructureBuilder.GetFieldType(Value);
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ internal static class Program
|
|||||||
Application.SetColorMode(SystemColorMode.System);
|
Application.SetColorMode(SystemColorMode.System);
|
||||||
#pragma warning restore WFO5001
|
#pragma warning restore WFO5001
|
||||||
|
|
||||||
Application.Run(new MainViewForm() { StartPosition = FormStartPosition.CenterScreen });
|
// Application.Run(new MainViewForm() { StartPosition = FormStartPosition.CenterScreen });
|
||||||
// Application.Run(new TestForm() { StartPosition = FormStartPosition.CenterScreen });
|
Application.Run(new TestForm() { StartPosition = FormStartPosition.CenterScreen });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+7
-4
@@ -49,13 +49,16 @@ partial class TestForm
|
|||||||
// entityTreeViewerControl1
|
// entityTreeViewerControl1
|
||||||
//
|
//
|
||||||
entityTreeViewerControl1.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
|
entityTreeViewerControl1.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
entityTreeViewerControl1.DepthSize = 20;
|
entityTreeViewerControl1.AutoScroll = true;
|
||||||
entityTreeViewerControl1.EntityView = null;
|
entityTreeViewerControl1.ButtonSize = 15;
|
||||||
|
entityTreeViewerControl1.DepthSize = 15;
|
||||||
entityTreeViewerControl1.Font = new Font("Consolas", 9F);
|
entityTreeViewerControl1.Font = new Font("Consolas", 9F);
|
||||||
|
entityTreeViewerControl1.HoverColor = SystemColors.ControlLight;
|
||||||
entityTreeViewerControl1.ItemHeight = 20;
|
entityTreeViewerControl1.ItemHeight = 20;
|
||||||
entityTreeViewerControl1.Location = new Point(12, 38);
|
entityTreeViewerControl1.Location = new Point(14, 46);
|
||||||
|
entityTreeViewerControl1.Margin = new Padding(3, 4, 3, 4);
|
||||||
entityTreeViewerControl1.Name = "entityTreeViewerControl1";
|
entityTreeViewerControl1.Name = "entityTreeViewerControl1";
|
||||||
entityTreeViewerControl1.Size = new Size(426, 606);
|
entityTreeViewerControl1.Size = new Size(424, 597);
|
||||||
entityTreeViewerControl1.TabIndex = 1;
|
entityTreeViewerControl1.TabIndex = 1;
|
||||||
//
|
//
|
||||||
// TestForm
|
// TestForm
|
||||||
|
|||||||
Reference in New Issue
Block a user