Обновление отображения

This commit is contained in:
2025-04-27 12:22:52 +04:00
parent 76167f1b24
commit 06d154eccc
9 changed files with 523 additions and 402 deletions
@@ -159,7 +159,6 @@ internal abstract class AbstractEntityProcessor(AonprdProcessorInput input)
List<Trait> traits = Context
.Traits.Include(t => t.Entity)
.ThenInclude(entity => entity.Name)
.Where(t => traitEntities.Contains(t.Entity))
.ToList();
+19
View File
@@ -0,0 +1,19 @@
namespace Pf2eViewer;
internal sealed class CoreBindingNavigator : BindingNavigator
{
public CoreBindingNavigator()
{
AddStandardItems();
if (DeleteItem != null)
{
DeleteItem.Visible = false;
}
if (AddNewItem != null)
{
AddNewItem.Visible = false;
}
}
}
-171
View File
@@ -1,171 +0,0 @@
using LinqToDB.SqlQuery;
using LinqToDB.Tools;
using Microsoft.EntityFrameworkCore;
using Pf2eModel;
using Pf2eModel.Model;
using Pf2eModel.Model.Base;
using Pf2eModel.Model.Enum;
using Pf2eModel.Model.Structure;
namespace Pf2eViewer;
public class DatabaseViewer
{
public readonly Pf2eDbContext Context = new();
private int _perPage = 30;
private int _page = 1;
private EntityType _entityType;
public int PerPage
{
get => _perPage;
set
{
_perPage = value;
UpdateView();
}
}
public int Page
{
get => _page;
set
{
_page = value;
UpdateView();
}
}
public EntityType EntityType
{
get => _entityType;
set
{
_entityType = value;
UpdateView();
}
}
public int Count { get; private set; }
public int MaxPage => Convert.ToInt32(Math.Ceiling(1.0 * Count / PerPage));
public ICollection<Entity> Entities { get; private set; } = [];
public delegate void ViewUpdateHandler();
public event ViewUpdateHandler? ViewUpdateStart;
public event ViewUpdateHandler? ViewUpdate;
public Entity? LastEntity;
public IEntity? LastSubEntity;
public delegate void ViewSelectHandler(Entity? entity, IEntity? subEntity);
public event ViewSelectHandler? ViewSelect;
public void UpdateView()
{
ViewUpdateStart?.Invoke();
Count = Context.Entities.Count(e => e.Type == EntityType);
if (_page < 1 || _page > MaxPage)
{
_page = Math.Min(MaxPage, Math.Max(1, _page));
}
Entities = Context
.Entities.Where(e => e.Type == EntityType)
.OrderBy(e => e.Id)
.Skip((Page - 1) * PerPage)
.Take(PerPage)
.ToList();
ViewUpdate?.Invoke();
}
public void Select(Entity entity)
{
Getter? getter = _getters.FirstOrDefault(g => g.Type == entity.Type);
Entity? fullEntity = Context
.Entities.Where(e => e.Id == entity.Id && e.Type == entity.Type)
.Include(e => e.Sources)
.ThenInclude(s => s.Source)
.Include(e => e.Keywords)
.Include(e => e.Externals)
.ThenInclude(x => x.Target)
.Include(e => e.Traits)
.ThenInclude(t => t.Entity)
.FirstOrDefault();
IEntity? subEntity =
(getter != null)
? getter.Get(entity.Id, Context)
: (IEntity?)Context.Find(EntityOfTypeAttribute.Resolve(entity), entity.Id);
ViewSelect?.Invoke(fullEntity, subEntity);
LastEntity = fullEntity;
LastSubEntity = subEntity;
}
private readonly ICollection<Getter> _getters =
[
new Getter<Ancestry>(
EntityType.Ancestry,
context => context.Ancestries.Include(a => a.AncestryBoosts)
),
new Getter<Archetype>(
EntityType.Archetype,
context =>
context
.Archetypes.Include(a => a.DedicationFeat)
.ThenInclude(f => f.Entity)
.Include(a => a.Feats)
.ThenInclude(f => f.Entity)
),
new Getter<Background>(
EntityType.Background,
context =>
context
.Backgrounds.Include(b => b.BackgroundBoosts)
.Include(b => b.BackgroundSkills)
.ThenInclude(t => t.Training)
.Include(b => b.BackgroundItems)
),
new Getter<Class>(
EntityType.Class,
context =>
context
.Classes.Include(c => c.ClassKeyAbilities)
.Include(c => c.ClassTrainings)
.ThenInclude(t => t.Training)
.Include(c => c.ClassProgressions)
),
new Getter<Feat>(
EntityType.Feat,
context =>
context.Feats.Include(f => f.Archetypes).ThenInclude(a => a.Entity).AsQueryable()
),
];
private abstract class Getter(EntityType type)
{
public readonly EntityType Type = type;
public abstract IEntity? Get(int id, Pf2eDbContext context);
}
private class Getter<T>(EntityType type, Func<Pf2eDbContext, IQueryable<T>> method)
: Getter(type)
where T : IEntity
{
public override IEntity? Get(int id, Pf2eDbContext context)
{
return method.Invoke(context).FirstOrDefault(c => c.Id == id);
}
}
}
+110
View File
@@ -0,0 +1,110 @@
namespace Pf2eViewer;
partial class DatabaseViewerControl
{
/// <summary>
/// Обязательная переменная конструктора.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Освободить все используемые ресурсы.
/// </summary>
/// <param name="disposing">истинно, если управляемый ресурс должен быть удален; иначе ложно.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Код, автоматически созданный конструктором компонентов
/// <summary>
/// Требуемый метод для поддержки конструктора — не изменяйте
/// содержимое этого метода с помощью редактора кода.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
BindingNavigator = new CoreBindingNavigator();
SearchTextBox = new TextBox();
DataGridView = new DataGridView();
DbBindingSource = new BindingSource(components);
PagesBindingSource = new BindingSource(components);
( BindingNavigator).BeginInit();
((System.ComponentModel.ISupportInitialize) DataGridView).BeginInit();
((System.ComponentModel.ISupportInitialize) DbBindingSource).BeginInit();
((System.ComponentModel.ISupportInitialize) PagesBindingSource).BeginInit();
SuspendLayout();
//
// BindingNavigator
//
BindingNavigator.AddNewItem = null;
BindingNavigator.DeleteItem = null;
BindingNavigator.ImeMode = ImeMode.NoControl;
BindingNavigator.LayoutStyle = ToolStripLayoutStyle.HorizontalStackWithOverflow;
BindingNavigator.Location = new Point(0, 0);
BindingNavigator.Name = "BindingNavigator";
BindingNavigator.Size = new Size(345, 25);
BindingNavigator.Stretch = true;
BindingNavigator.TabIndex = 1;
BindingNavigator.Text = "coreBindingNavigator1";
BindingNavigator.RefreshItems += BindingNavigator_RefreshItems;
//
// SearchTextBox
//
SearchTextBox.Dock = DockStyle.Top;
SearchTextBox.Location = new Point(0, 25);
SearchTextBox.Name = "SearchTextBox";
SearchTextBox.PlaceholderText = "Поиск";
SearchTextBox.Size = new Size(345, 23);
SearchTextBox.TabIndex = 3;
//
// DataGridView
//
DataGridView.AllowUserToAddRows = false;
DataGridView.AllowUserToDeleteRows = false;
DataGridView.AutoGenerateColumns = false;
DataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader;
DataGridView.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCellsExceptHeaders;
DataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
DataGridView.DataSource = DbBindingSource;
DataGridView.Dock = DockStyle.Fill;
DataGridView.Location = new Point(0, 48);
DataGridView.MultiSelect = false;
DataGridView.Name = "DataGridView";
DataGridView.ReadOnly = true;
DataGridView.RowHeadersVisible = false;
DataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
DataGridView.Size = new Size(345, 345);
DataGridView.TabIndex = 4;
DataGridView.RowStateChanged += DataGridView_RowStateChanged;
//
// DatabaseViewerControl
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
Controls.Add(DataGridView);
Controls.Add(SearchTextBox);
Controls.Add(BindingNavigator);
Name = "DatabaseViewerControl";
Size = new Size(345, 393);
Load += DatabaseViewerControl_Load;
( BindingNavigator).EndInit();
((System.ComponentModel.ISupportInitialize) DataGridView).EndInit();
((System.ComponentModel.ISupportInitialize) DbBindingSource).EndInit();
((System.ComponentModel.ISupportInitialize) PagesBindingSource).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private CoreBindingNavigator BindingNavigator;
private TextBox SearchTextBox;
private DataGridView DataGridView;
private BindingSource DbBindingSource;
private BindingSource PagesBindingSource;
}
+143
View File
@@ -0,0 +1,143 @@
using Pf2eModel;
using Pf2eModel.Model.Base;
using Pf2eModel.Model.Common.I18n;
using Pf2eModel.Model.Enum;
namespace Pf2eViewer;
public partial class DatabaseViewerControl : UserControl
{
public readonly Pf2eDbContext Context = new();
private int _perPage = 30;
private int _page = 1;
private EntityType _type;
public int PerPage
{
get => _perPage;
set
{
_perPage = value;
UpdateView();
}
}
public int Page
{
get => _page;
set
{
_page = value;
UpdateView();
}
}
public int Count { get; private set; }
public int MaxPage => Convert.ToInt32(Math.Ceiling(1.0 * Count / PerPage));
public EntityView CurrentEntity { get; private set; } = null!;
public EntityType Type
{
get => _type;
set
{
_type = value;
UpdateView();
}
}
internal bool _updating = false;
public DatabaseViewerControl()
{
InitializeComponent();
BindingNavigator.BindingSource = DbBindingSource;
DataGridView.AutoGenerateColumns = true;
DataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
}
private void DatabaseViewerControl_Load(object sender, EventArgs e)
{
UpdateView();
}
private void BindingNavigator_RefreshItems(object sender, EventArgs e)
{
if (_updating)
{
return;
}
Page = (int)(BindingNavigator?.BindingSource?.Current ?? 1);
UpdateView();
}
public void UpdateView()
{
_updating = true;
IQueryable<Entity> query = Context.Entities.Where(e =>
e.Type == Type
&& (
// ReSharper disable once EntityFramework.UnsupportedServerSideFunctionCall
SearchTextBox.Text == ""
|| Pf2eDbContext.LocaleSearch(e.Name, SearchTextBox.Text)
)
);
Count = query.Count();
PagesBindingSource.DataSource = Enumerable.Range(1, MaxPage).ToList();
BindingNavigator.BindingSource = PagesBindingSource;
DbBindingSource.DataSource = query
.Skip((Page - 1) * PerPage)
.Take(PerPage)
.Select(e => new EntityGridRow(e))
.ToList();
if (DataGridView.Rows.Count > 0)
{
DataGridView.Rows[0].Selected = true;
}
DataGridView.Update();
_updating = false;
}
private void DataGridView_RowStateChanged(object sender, DataGridViewRowStateChangedEventArgs e)
{
if (DataGridView.SelectedRows.Count == 0)
{
return;
}
EntityGridRow data = (EntityGridRow)DataGridView.SelectedRows[0].DataBoundItem;
CurrentEntity = new(Context, Type, data.Id);
EntityChange?.Invoke(CurrentEntity);
}
public delegate void EntityChangeHandler(EntityView newEntity);
public event EntityChangeHandler? EntityChange;
internal class EntityGridRow(Entity e)
{
public int Id { get; set; } = e.Id;
public string Name { get; set; } = e.Name[LocaleType.English];
public EntityRarity Rarity { get; set; } = e.Rarity;
private readonly Entity _e = e;
public Entity GetEntity() => _e;
}
}
+126
View File
@@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="DbBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="PagesBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>163, 17</value>
</metadata>
</root>
+96
View File
@@ -0,0 +1,96 @@
using Microsoft.EntityFrameworkCore;
using Pf2eModel;
using Pf2eModel.Model;
using Pf2eModel.Model.Base;
using Pf2eModel.Model.Enum;
using Pf2eModel.Model.Structure;
namespace Pf2eViewer;
public class EntityView
{
public Entity? Entity;
public IEntity? SubEntity;
public EntityView(Pf2eDbContext context, EntityType type, int id)
{
Getter? getter = _getters.FirstOrDefault(g => g.Type == type);
Entity fullEntity =
context
.Entities.Where(e => e.Id == id && e.Type == type)
.Include(e => e.Sources)
.ThenInclude(s => s.Source)
.Include(e => e.Keywords)
.Include(e => e.Externals)
.ThenInclude(x => x.Target)
.Include(e => e.Traits)
.ThenInclude(t => t.Entity)
.FirstOrDefault() ?? throw new Exception("Entity is null");
IEntity? subEntity =
(getter != null)
? getter.Get(id, context)
: (IEntity?)context.Find(EntityOfTypeAttribute.Resolve(fullEntity), id);
Entity = fullEntity;
SubEntity = subEntity;
}
private readonly ICollection<Getter> _getters =
[
new Getter<Ancestry>(
EntityType.Ancestry,
context => context.Ancestries.Include(a => a.AncestryBoosts)
),
new Getter<Archetype>(
EntityType.Archetype,
context =>
context
.Archetypes.Include(a => a.DedicationFeat)
.ThenInclude(f => f.Entity)
.Include(a => a.Feats)
.ThenInclude(f => f.Entity)
),
new Getter<Background>(
EntityType.Background,
context =>
context
.Backgrounds.Include(b => b.BackgroundBoosts)
.Include(b => b.BackgroundSkills)
.ThenInclude(t => t.Training)
.Include(b => b.BackgroundItems)
),
new Getter<Class>(
EntityType.Class,
context =>
context
.Classes.Include(c => c.ClassKeyAbilities)
.Include(c => c.ClassTrainings)
.ThenInclude(t => t.Training)
.Include(c => c.ClassProgressions)
),
new Getter<Feat>(
EntityType.Feat,
context =>
context.Feats.Include(f => f.Archetypes).ThenInclude(a => a.Entity).AsQueryable()
),
];
private abstract class Getter(EntityType type)
{
public readonly EntityType Type = type;
public abstract IEntity? Get(int id, Pf2eDbContext context);
}
private class Getter<T>(EntityType type, Func<Pf2eDbContext, IQueryable<T>> method)
: Getter(type)
where T : IEntity
{
public override IEntity? Get(int id, Pf2eDbContext context)
{
return method.Invoke(context).FirstOrDefault(c => c.Id == id);
}
}
}
+9 -118
View File
@@ -31,14 +31,7 @@ partial class MainViewForm
RootSplitContainer = new SplitContainer();
InnerSplitContainer = new SplitContainer();
TypesListBox = new ListBox();
EntityGridView = new DataGridView();
PaginationPagel = new Panel();
PageTextBox = new TextBox();
PaginationLabel = new TextBox();
LastPageButton = new Button();
NextPageButton = new Button();
PrevPageButton = new Button();
FirstPageButton = new Button();
DatabaseViewer = new DatabaseViewerControl();
ResultSplitContainer = new SplitContainer();
JsonWebView = new Microsoft.Web.WebView2.WinForms.WebView2();
DescriptionTextBox = new TextBox();
@@ -50,8 +43,6 @@ partial class MainViewForm
InnerSplitContainer.Panel1.SuspendLayout();
InnerSplitContainer.Panel2.SuspendLayout();
InnerSplitContainer.SuspendLayout();
((System.ComponentModel.ISupportInitialize) EntityGridView).BeginInit();
PaginationPagel.SuspendLayout();
((System.ComponentModel.ISupportInitialize) ResultSplitContainer).BeginInit();
ResultSplitContainer.Panel1.SuspendLayout();
ResultSplitContainer.Panel2.SuspendLayout();
@@ -91,8 +82,7 @@ partial class MainViewForm
//
// InnerSplitContainer.Panel2
//
InnerSplitContainer.Panel2.Controls.Add(EntityGridView);
InnerSplitContainer.Panel2.Controls.Add(PaginationPagel);
InnerSplitContainer.Panel2.Controls.Add(DatabaseViewer);
InnerSplitContainer.Size = new Size(254, 688);
InnerSplitContainer.SplitterDistance = 102;
InnerSplitContainer.TabIndex = 1;
@@ -108,102 +98,13 @@ partial class MainViewForm
TypesListBox.TabIndex = 0;
TypesListBox.SelectedIndexChanged += TypesListBox_SelectedIndexChanged;
//
// EntityGridView
// EntityView
//
EntityGridView.AllowUserToAddRows = false;
EntityGridView.AllowUserToDeleteRows = false;
EntityGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
EntityGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
EntityGridView.Dock = DockStyle.Fill;
EntityGridView.Location = new Point(0, 53);
EntityGridView.MultiSelect = false;
EntityGridView.Name = "EntityGridView";
EntityGridView.ReadOnly = true;
EntityGridView.RowHeadersVisible = false;
EntityGridView.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.AutoSizeToDisplayedHeaders;
EntityGridView.ShowEditingIcon = false;
EntityGridView.Size = new Size(254, 529);
EntityGridView.TabIndex = 0;
EntityGridView.RowStateChanged += EntityGridView_RowStateChanged;
//
// PaginationPagel
//
PaginationPagel.Controls.Add(PageTextBox);
PaginationPagel.Controls.Add(PaginationLabel);
PaginationPagel.Controls.Add(LastPageButton);
PaginationPagel.Controls.Add(NextPageButton);
PaginationPagel.Controls.Add(PrevPageButton);
PaginationPagel.Controls.Add(FirstPageButton);
PaginationPagel.Dock = DockStyle.Top;
PaginationPagel.Location = new Point(0, 0);
PaginationPagel.Name = "PaginationPagel";
PaginationPagel.Size = new Size(254, 53);
PaginationPagel.TabIndex = 1;
//
// PageTextBox
//
PageTextBox.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
PageTextBox.Location = new Point(81, 4);
PageTextBox.Name = "PageTextBox";
PageTextBox.Size = new Size(92, 23);
PageTextBox.TabIndex = 8;
PageTextBox.Text = "1";
PageTextBox.TextAlign = HorizontalAlignment.Center;
PageTextBox.KeyPress += PageTextBox_KeyPress;
//
// PaginationLabel
//
PaginationLabel.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
PaginationLabel.BorderStyle = BorderStyle.None;
PaginationLabel.Location = new Point(3, 31);
PaginationLabel.Name = "PaginationLabel";
PaginationLabel.ReadOnly = true;
PaginationLabel.Size = new Size(248, 16);
PaginationLabel.TabIndex = 7;
PaginationLabel.Text = "Всего";
PaginationLabel.TextAlign = HorizontalAlignment.Center;
//
// LastPageButton
//
LastPageButton.Anchor = AnchorStyles.Top | AnchorStyles.Right;
LastPageButton.Location = new Point(218, 3);
LastPageButton.Name = "LastPageButton";
LastPageButton.Size = new Size(33, 23);
LastPageButton.TabIndex = 3;
LastPageButton.Text = ">>";
LastPageButton.UseVisualStyleBackColor = true;
LastPageButton.Click += LastPageButton_Click;
//
// NextPageButton
//
NextPageButton.Anchor = AnchorStyles.Top | AnchorStyles.Right;
NextPageButton.Location = new Point(179, 3);
NextPageButton.Name = "NextPageButton";
NextPageButton.Size = new Size(33, 23);
NextPageButton.TabIndex = 2;
NextPageButton.Text = ">";
NextPageButton.UseVisualStyleBackColor = true;
NextPageButton.Click += NextPageButton_Click;
//
// PrevPageButton
//
PrevPageButton.Location = new Point(42, 3);
PrevPageButton.Name = "PrevPageButton";
PrevPageButton.Size = new Size(33, 23);
PrevPageButton.TabIndex = 1;
PrevPageButton.Text = "<";
PrevPageButton.UseVisualStyleBackColor = true;
PrevPageButton.Click += PrevPageButton_Click;
//
// FirstPageButton
//
FirstPageButton.Location = new Point(3, 3);
FirstPageButton.Name = "FirstPageButton";
FirstPageButton.Size = new Size(33, 23);
FirstPageButton.TabIndex = 0;
FirstPageButton.Text = "<<";
FirstPageButton.UseVisualStyleBackColor = true;
FirstPageButton.Click += FirstPageButton_Click;
DatabaseViewer.Dock = DockStyle.Fill;
DatabaseViewer.Location = new Point(0, 0);
DatabaseViewer.Name = "DatabaseViewer";
DatabaseViewer.Size = new Size(254, 582);
DatabaseViewer.TabIndex = 0;
//
// ResultSplitContainer
//
@@ -263,9 +164,6 @@ partial class MainViewForm
InnerSplitContainer.Panel2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize) InnerSplitContainer).EndInit();
InnerSplitContainer.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize) EntityGridView).EndInit();
PaginationPagel.ResumeLayout(false);
PaginationPagel.PerformLayout();
ResultSplitContainer.Panel1.ResumeLayout(false);
ResultSplitContainer.Panel2.ResumeLayout(false);
ResultSplitContainer.Panel2.PerformLayout();
@@ -280,15 +178,8 @@ partial class MainViewForm
private SplitContainer RootSplitContainer;
private SplitContainer InnerSplitContainer;
private ListBox TypesListBox;
private DataGridView EntityGridView;
private SplitContainer ResultSplitContainer;
private TextBox DescriptionTextBox;
private Panel PaginationPagel;
private Button LastPageButton;
private Button NextPageButton;
private Button PrevPageButton;
private Button FirstPageButton;
private TextBox PageTextBox;
private TextBox PaginationLabel;
private Microsoft.Web.WebView2.WinForms.WebView2 JsonWebView;
private DatabaseViewerControl DatabaseViewer;
}
+20 -112
View File
@@ -1,6 +1,4 @@
using System.Windows.Forms;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
using Pf2eModel;
@@ -9,7 +7,6 @@ using Pf2eModel.Model.Base;
using Pf2eModel.Model.Common.I18n;
using Pf2eModel.Model.Enum;
using Pf2eViewer.Converters;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
namespace Pf2eViewer;
@@ -19,7 +16,7 @@ public partial class MainViewForm : Form
public readonly string JsonViewerHtml;
public readonly DatabaseViewer Viewer = new();
public readonly EntityView Viewer;
public MainViewForm()
{
@@ -27,16 +24,12 @@ public partial class MainViewForm : Form
_ = new DarkModeCS(this) { ColorMode = DarkModeCS.DisplayMode.SystemDefault };
Reset();
EntityGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
using StreamReader reader = new("Resources/json-viewer.html");
JsonViewerHtml = reader.ReadToEnd();
Viewer.ViewUpdateStart += Viewer_ViewUpdateStart;
Viewer.ViewUpdate += Viewer_ViewUpdate;
Viewer.ViewSelect += Viewer_ViewSelect;
DatabaseViewer.EntityChange += DatabaseViewer_EntityChange;
Reset();
}
public void Reset()
@@ -44,45 +37,21 @@ public partial class MainViewForm : Form
Context.Dispose();
Context = new();
TypesListBox.DataSource = Context.Entities.Select(e => e.Type).Distinct().ToList();
TypesListBox.DataSource = Context
.Entities.Select(e => e.Type)
.Distinct()
.OrderBy(t => t.ToString())
.ToList();
TypesListBox.SelectedIndex = 0;
}
private void ToggleFreeze(bool state)
{
EntityGridView.Visible = state;
JsonWebView.Visible = state;
FirstPageButton.Enabled = state;
PrevPageButton.Enabled = state;
NextPageButton.Enabled = state;
LastPageButton.Enabled = state;
PageTextBox.Enabled = state;
// EntityGridView.Visible = state;
// JsonWebView.Visible = state;
}
// Viewer events
private void Viewer_ViewUpdateStart()
{
ToggleFreeze(false);
}
private void Viewer_ViewUpdate()
{
EntityGridView.DataSource = Viewer.Entities.Select(e => new EntityGridRow(e));
PaginationLabel.Text = $@"Всего: {Viewer.Count} объектов, {Viewer.MaxPage} страниц";
FirstPageButton.Enabled = Viewer.Page > 1;
PrevPageButton.Enabled = Viewer.Page > 1;
NextPageButton.Enabled = Viewer.Page < Viewer.MaxPage;
LastPageButton.Enabled = Viewer.Page < Viewer.MaxPage;
ToggleFreeze(true);
}
private void Viewer_ViewSelect(Entity? entity, IEntity? subEntity)
private void DatabaseViewer_EntityChange(EntityView newEntity)
{
JsonSerializerSettings settings = new()
{
@@ -95,15 +64,15 @@ public partial class MainViewForm : Form
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
};
string result = JsonConvert.SerializeObject(entity, settings);
string subResult = JsonConvert.SerializeObject(subEntity, settings);
string result = JsonConvert.SerializeObject(newEntity.Entity, settings);
string subResult = JsonConvert.SerializeObject(newEntity.SubEntity, settings);
string json = result[..^1] + $",\"SubEntity\":{subResult}}}";
RenderJson(json);
}
// Form events
DescriptionTextBox.Text = newEntity.Entity!.Description;
}
private void TypesListBox_SelectedIndexChanged(object sender, EventArgs _)
{
@@ -112,58 +81,8 @@ public partial class MainViewForm : Form
return;
}
Viewer.Page = 1;
}
private void FirstPageButton_Click(object sender, EventArgs e)
{
Viewer.Page = 1;
}
private void PrevPageButton_Click(object sender, EventArgs e)
{
Viewer.Page--;
}
private void NextPageButton_Click(object sender, EventArgs e)
{
Viewer.Page++;
}
private void LastPageButton_Click(object sender, EventArgs e)
{
Viewer.Page = Viewer.MaxPage;
}
private void PageTextBox_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar))
{
e.Handled = true;
}
if (e.KeyChar == (char)Keys.Return)
{
Viewer.Page = Convert.ToInt32(PageTextBox.Text);
}
}
private void EntityGridView_RowStateChanged(
object sender,
DataGridViewRowStateChangedEventArgs e
)
{
int rowsCount = EntityGridView.SelectedRows.Count;
if (rowsCount is 0 or > 1)
{
return;
}
DataGridViewRow row = EntityGridView.SelectedRows[0];
EntityGridRow data = (EntityGridRow)row.DataBoundItem;
Viewer.Select(data.GetEntity());
DatabaseViewer.Type = (EntityType)TypesListBox.SelectedItem;
// Viewer.Page = 1;
}
public void RenderJson(string json)
@@ -184,17 +103,6 @@ public partial class MainViewForm : Form
)
{
JsonWebView.Visible = true;
Viewer_ViewSelect(Viewer.LastEntity, Viewer.LastSubEntity);
DatabaseViewer_EntityChange(DatabaseViewer.CurrentEntity);
}
}
internal class EntityGridRow(Entity e)
{
public int Id { get; set; } = e.Id;
public string Name { get; set; } = e.Name[LocaleType.English];
public EntityRarity Rarity { get; set; } = e.Rarity;
private readonly Entity _e = e;
public Entity GetEntity() => _e;
}