mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-03-21 17:48:28 -05:00
Faster box hover preview
Render it manually rather than let controls be goofy with draw calls.
This commit is contained in:
parent
5b42ff746d
commit
662c3db7dc
231
PKHeX.WinForms/Controls/Slots/PokePreview.Designer.cs
generated
231
PKHeX.WinForms/Controls/Slots/PokePreview.Designer.cs
generated
|
|
@ -28,216 +28,13 @@ protected override void Dispose(bool disposing)
|
|||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
PAN_All = new System.Windows.Forms.Panel();
|
||||
FLP_List = new System.Windows.Forms.FlowLayoutPanel();
|
||||
L_LinesBeforeMoves = new System.Windows.Forms.Label();
|
||||
FLP_Moves = new System.Windows.Forms.FlowLayoutPanel();
|
||||
Move1 = new MoveDisplay();
|
||||
Move2 = new MoveDisplay();
|
||||
Move3 = new MoveDisplay();
|
||||
Move4 = new MoveDisplay();
|
||||
L_HintIllegal = new System.Windows.Forms.Label();
|
||||
L_LinesAfterMoves = new System.Windows.Forms.Label();
|
||||
PAN_Top = new System.Windows.Forms.Panel();
|
||||
FLP_Top = new System.Windows.Forms.FlowLayoutPanel();
|
||||
PB_Ball = new System.Windows.Forms.PictureBox();
|
||||
L_Name = new System.Windows.Forms.Label();
|
||||
PB_Gender = new System.Windows.Forms.PictureBox();
|
||||
PAN_All.SuspendLayout();
|
||||
FLP_List.SuspendLayout();
|
||||
FLP_Moves.SuspendLayout();
|
||||
PAN_Top.SuspendLayout();
|
||||
FLP_Top.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)PB_Ball).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)PB_Gender).BeginInit();
|
||||
SuspendLayout();
|
||||
//
|
||||
// PAN_All
|
||||
//
|
||||
PAN_All.AutoSize = true;
|
||||
PAN_All.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
PAN_All.BackColor = System.Drawing.SystemColors.Window;
|
||||
PAN_All.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
PAN_All.Controls.Add(FLP_List);
|
||||
PAN_All.Controls.Add(PAN_Top);
|
||||
PAN_All.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
PAN_All.Location = new System.Drawing.Point(0, 0);
|
||||
PAN_All.Margin = new System.Windows.Forms.Padding(0);
|
||||
PAN_All.Name = "PAN_All";
|
||||
PAN_All.Size = new System.Drawing.Size(148, 214);
|
||||
PAN_All.TabIndex = 19;
|
||||
//
|
||||
// FLP_List
|
||||
//
|
||||
FLP_List.AutoSize = true;
|
||||
FLP_List.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
FLP_List.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
FLP_List.Controls.Add(L_LinesBeforeMoves);
|
||||
FLP_List.Controls.Add(FLP_Moves);
|
||||
FLP_List.Controls.Add(L_HintIllegal);
|
||||
FLP_List.Controls.Add(L_LinesAfterMoves);
|
||||
FLP_List.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
FLP_List.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
|
||||
FLP_List.Location = new System.Drawing.Point(0, 34);
|
||||
FLP_List.Margin = new System.Windows.Forms.Padding(0);
|
||||
FLP_List.Name = "FLP_List";
|
||||
FLP_List.Size = new System.Drawing.Size(146, 178);
|
||||
FLP_List.TabIndex = 1;
|
||||
FLP_List.WrapContents = false;
|
||||
//
|
||||
// L_LinesBeforeMoves
|
||||
//
|
||||
L_LinesBeforeMoves.AutoSize = true;
|
||||
L_LinesBeforeMoves.Location = new System.Drawing.Point(2, 4);
|
||||
L_LinesBeforeMoves.Margin = new System.Windows.Forms.Padding(2, 4, 0, 0);
|
||||
L_LinesBeforeMoves.Name = "L_LinesBeforeMoves";
|
||||
L_LinesBeforeMoves.Size = new System.Drawing.Size(36, 17);
|
||||
L_LinesBeforeMoves.TabIndex = 5;
|
||||
L_LinesBeforeMoves.Text = "Stats";
|
||||
//
|
||||
// FLP_Moves
|
||||
//
|
||||
FLP_Moves.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
FLP_Moves.AutoSize = true;
|
||||
FLP_Moves.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
FLP_Moves.Controls.Add(Move1);
|
||||
FLP_Moves.Controls.Add(Move2);
|
||||
FLP_Moves.Controls.Add(Move3);
|
||||
FLP_Moves.Controls.Add(Move4);
|
||||
FLP_List.SetFlowBreak(FLP_Moves, true);
|
||||
FLP_Moves.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
|
||||
FLP_Moves.Location = new System.Drawing.Point(0, 25);
|
||||
FLP_Moves.Margin = new System.Windows.Forms.Padding(0, 4, 0, 8);
|
||||
FLP_Moves.Name = "FLP_Moves";
|
||||
FLP_Moves.Size = new System.Drawing.Size(142, 96);
|
||||
FLP_Moves.TabIndex = 7;
|
||||
FLP_Moves.WrapContents = false;
|
||||
//
|
||||
// Move1
|
||||
//
|
||||
Move1.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
Move1.AutoSize = true;
|
||||
Move1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
Move1.Location = new System.Drawing.Point(4, 0);
|
||||
Move1.Margin = new System.Windows.Forms.Padding(4, 0, 0, 0);
|
||||
Move1.Name = "Move1";
|
||||
Move1.Size = new System.Drawing.Size(138, 24);
|
||||
Move1.TabIndex = 1;
|
||||
//
|
||||
// Move2
|
||||
//
|
||||
Move2.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
Move2.AutoSize = true;
|
||||
Move2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
Move2.Location = new System.Drawing.Point(4, 24);
|
||||
Move2.Margin = new System.Windows.Forms.Padding(4, 0, 0, 0);
|
||||
Move2.Name = "Move2";
|
||||
Move2.Size = new System.Drawing.Size(138, 24);
|
||||
Move2.TabIndex = 2;
|
||||
//
|
||||
// Move3
|
||||
//
|
||||
Move3.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
Move3.AutoSize = true;
|
||||
Move3.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
Move3.Location = new System.Drawing.Point(4, 48);
|
||||
Move3.Margin = new System.Windows.Forms.Padding(4, 0, 0, 0);
|
||||
Move3.Name = "Move3";
|
||||
Move3.Size = new System.Drawing.Size(138, 24);
|
||||
Move3.TabIndex = 3;
|
||||
//
|
||||
// Move4
|
||||
//
|
||||
Move4.AutoSize = true;
|
||||
Move4.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
Move4.Location = new System.Drawing.Point(4, 72);
|
||||
Move4.Margin = new System.Windows.Forms.Padding(4, 0, 0, 0);
|
||||
Move4.Name = "Move4";
|
||||
Move4.Size = new System.Drawing.Size(138, 24);
|
||||
Move4.TabIndex = 4;
|
||||
//
|
||||
// L_HintIllegal
|
||||
//
|
||||
L_HintIllegal.AutoSize = true;
|
||||
L_HintIllegal.Location = new System.Drawing.Point(2, 133);
|
||||
L_HintIllegal.Margin = new System.Windows.Forms.Padding(2, 4, 0, 4);
|
||||
L_HintIllegal.Name = "L_HintIllegal";
|
||||
L_HintIllegal.Size = new System.Drawing.Size(42, 17);
|
||||
L_HintIllegal.TabIndex = 8;
|
||||
L_HintIllegal.Text = "Illegal";
|
||||
//
|
||||
// L_LinesAfterMoves
|
||||
//
|
||||
L_LinesAfterMoves.AutoSize = true;
|
||||
L_LinesAfterMoves.Location = new System.Drawing.Point(2, 158);
|
||||
L_LinesAfterMoves.Margin = new System.Windows.Forms.Padding(2, 4, 0, 4);
|
||||
L_LinesAfterMoves.Name = "L_LinesAfterMoves";
|
||||
L_LinesAfterMoves.Size = new System.Drawing.Size(30, 17);
|
||||
L_LinesAfterMoves.TabIndex = 6;
|
||||
L_LinesAfterMoves.Text = "Info";
|
||||
//
|
||||
// PAN_Top
|
||||
//
|
||||
PAN_Top.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
PAN_Top.Controls.Add(FLP_Top);
|
||||
PAN_Top.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
PAN_Top.Location = new System.Drawing.Point(0, 0);
|
||||
PAN_Top.Margin = new System.Windows.Forms.Padding(0);
|
||||
PAN_Top.Name = "PAN_Top";
|
||||
PAN_Top.Size = new System.Drawing.Size(146, 34);
|
||||
PAN_Top.TabIndex = 0;
|
||||
//
|
||||
// FLP_Top
|
||||
//
|
||||
FLP_Top.Controls.Add(PB_Ball);
|
||||
FLP_Top.Controls.Add(L_Name);
|
||||
FLP_Top.Controls.Add(PB_Gender);
|
||||
FLP_Top.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
FLP_Top.Location = new System.Drawing.Point(0, 0);
|
||||
FLP_Top.Margin = new System.Windows.Forms.Padding(0);
|
||||
FLP_Top.Name = "FLP_Top";
|
||||
FLP_Top.Size = new System.Drawing.Size(144, 32);
|
||||
FLP_Top.TabIndex = 71;
|
||||
//
|
||||
// PB_Ball
|
||||
//
|
||||
PB_Ball.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;
|
||||
PB_Ball.Location = new System.Drawing.Point(4, 4);
|
||||
PB_Ball.Margin = new System.Windows.Forms.Padding(4, 4, 0, 0);
|
||||
PB_Ball.Name = "PB_Ball";
|
||||
PB_Ball.Size = new System.Drawing.Size(24, 24);
|
||||
PB_Ball.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage;
|
||||
PB_Ball.TabIndex = 68;
|
||||
PB_Ball.TabStop = false;
|
||||
//
|
||||
// L_Name
|
||||
//
|
||||
L_Name.Location = new System.Drawing.Point(28, 4);
|
||||
L_Name.Margin = new System.Windows.Forms.Padding(0, 4, 0, 0);
|
||||
L_Name.Name = "L_Name";
|
||||
L_Name.Size = new System.Drawing.Size(88, 24);
|
||||
L_Name.TabIndex = 0;
|
||||
L_Name.Text = "Species";
|
||||
L_Name.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// PB_Gender
|
||||
//
|
||||
PB_Gender.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;
|
||||
PB_Gender.Location = new System.Drawing.Point(116, 4);
|
||||
PB_Gender.Margin = new System.Windows.Forms.Padding(0, 4, 4, 0);
|
||||
PB_Gender.Name = "PB_Gender";
|
||||
PB_Gender.Size = new System.Drawing.Size(24, 24);
|
||||
PB_Gender.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage;
|
||||
PB_Gender.TabIndex = 70;
|
||||
PB_Gender.TabStop = false;
|
||||
//
|
||||
// PokePreview
|
||||
//
|
||||
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
|
||||
AutoSize = true;
|
||||
AutoSize = false;
|
||||
AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
ClientSize = new System.Drawing.Size(148, 214);
|
||||
Controls.Add(PAN_All);
|
||||
FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
|
|
@ -245,36 +42,10 @@ private void InitializeComponent()
|
|||
ShowIcon = false;
|
||||
ShowInTaskbar = false;
|
||||
Text = "PokePreview";
|
||||
PAN_All.ResumeLayout(false);
|
||||
PAN_All.PerformLayout();
|
||||
FLP_List.ResumeLayout(false);
|
||||
FLP_List.PerformLayout();
|
||||
FLP_Moves.ResumeLayout(false);
|
||||
FLP_Moves.PerformLayout();
|
||||
PAN_Top.ResumeLayout(false);
|
||||
FLP_Top.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)PB_Ball).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)PB_Gender).EndInit();
|
||||
ResumeLayout(false);
|
||||
PerformLayout();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Panel PAN_All;
|
||||
private System.Windows.Forms.FlowLayoutPanel FLP_List;
|
||||
private System.Windows.Forms.Label L_LinesBeforeMoves;
|
||||
private System.Windows.Forms.Panel PAN_Top;
|
||||
private System.Windows.Forms.Label L_Name;
|
||||
private System.Windows.Forms.PictureBox PB_Ball;
|
||||
private System.Windows.Forms.PictureBox PB_Gender;
|
||||
private MoveDisplay Move1;
|
||||
private MoveDisplay Move2;
|
||||
private MoveDisplay Move3;
|
||||
private MoveDisplay Move4;
|
||||
private System.Windows.Forms.Label L_LinesAfterMoves;
|
||||
private System.Windows.Forms.FlowLayoutPanel FLP_Moves;
|
||||
private System.Windows.Forms.FlowLayoutPanel FLP_Top;
|
||||
private System.Windows.Forms.Label L_HintIllegal;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,27 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using PKHeX.Core;
|
||||
using PKHeX.Drawing.Misc;
|
||||
using PKHeX.Drawing.PokeSprite;
|
||||
|
||||
namespace PKHeX.WinForms.Controls;
|
||||
|
||||
public partial class PokePreview : Form
|
||||
public sealed partial class PokePreview : Form
|
||||
{
|
||||
/// <summary> Minimum width to display the form. </summary>
|
||||
private readonly int InitialWidth;
|
||||
|
||||
private readonly int InitialNameWidth;
|
||||
|
||||
private const int interiorMargin = 4; // 2x pixel border on each side
|
||||
|
||||
public PokePreview()
|
||||
{
|
||||
InitializeComponent();
|
||||
InitialWidth = Width;
|
||||
InitialNameWidth = L_Name.Width;
|
||||
L_HintIllegal.ForeColor = WinFormsUtil.ColorWarn;
|
||||
}
|
||||
|
||||
private static readonly Image[] GenderImages =
|
||||
[
|
||||
Properties.Resources.gender_0,
|
||||
|
|
@ -29,30 +17,323 @@ public PokePreview()
|
|||
Properties.Resources.gender_2,
|
||||
];
|
||||
|
||||
public void Populate(PKM pk, in BattleTemplateExportSettings settings, in LegalityLocalizationContext ctx)
|
||||
private readonly List<RenderTextLine> TextLinesPre = [];
|
||||
private readonly List<RenderMoveLine> MoveLines = [];
|
||||
private readonly List<RenderTextLine> TextLinesHint = [];
|
||||
private readonly List<RenderTextLine> TextLinesEncounter = [];
|
||||
|
||||
private string HeaderName = string.Empty;
|
||||
private Image? HeaderBall;
|
||||
private Image? HeaderGender;
|
||||
|
||||
private const int Border = 1;
|
||||
private const int HeaderTopPadding = 4;
|
||||
private const int HeaderBottomPadding = 4;
|
||||
private const int HeaderLeftPadding = 4;
|
||||
private const int HeaderRightPadding = 4;
|
||||
private const int HeaderIconGap = 2;
|
||||
|
||||
private const int BodyTopPadding = 2;
|
||||
private const int BodyBottomPadding = 2;
|
||||
private const int BodyLeftPadding = 4;
|
||||
private const int BodyRightPadding = 4;
|
||||
|
||||
private const int TextSectionTopPadding = 2;
|
||||
private const int TextSectionBottomPadding = 2;
|
||||
private const int TextLineSpacing = 1;
|
||||
|
||||
private const int MoveIconTextGap = 2;
|
||||
private const int MoveSectionTopPadding = 4;
|
||||
private const int MoveSectionBottomPadding = 8;
|
||||
|
||||
private const int IconSize = 24;
|
||||
|
||||
private static Color IllegalTextColor => WinFormsUtil.ColorWarn;
|
||||
|
||||
public PokePreview()
|
||||
{
|
||||
int width = PopulateHeader(pk, settings);
|
||||
PopulateMoves(pk, ctx.Analysis, settings, ref width);
|
||||
PopulateText(pk, ctx, settings, width);
|
||||
InitializeComponent();
|
||||
|
||||
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw, true);
|
||||
UpdateStyles();
|
||||
}
|
||||
|
||||
private int PopulateHeader(PKM pk, in BattleTemplateExportSettings settings)
|
||||
public void Populate(PKM pk, in BattleTemplateExportSettings settings, in LegalityLocalizationContext ctx)
|
||||
{
|
||||
var name = GetNameTitle(pk, settings);
|
||||
var size = MeasureSize(name, L_Name.Font);
|
||||
L_Name.Width = Math.Max(InitialNameWidth, size.Width);
|
||||
L_Name.Text = name;
|
||||
var main = Main.Settings;
|
||||
HeaderName = GetNameTitle(pk, settings);
|
||||
|
||||
PopulateBall(pk);
|
||||
PopulateGender(pk);
|
||||
if (pk.Format > 2)
|
||||
HeaderBall = GetBallImage(pk);
|
||||
else
|
||||
HeaderBall = null;
|
||||
|
||||
var width = L_Name.Width + PB_Ball.Width + PB_Ball.Margin.Horizontal + PB_Gender.Width + PB_Gender.Margin.Horizontal + interiorMargin;
|
||||
return Math.Max(InitialWidth, width);
|
||||
if (pk.Format != 1 || main.EntityEditor.ShowGenderGen1)
|
||||
HeaderGender = GetGenderImage(pk);
|
||||
else
|
||||
HeaderGender = null;
|
||||
|
||||
TextLinesPre.Clear();
|
||||
MoveLines.Clear();
|
||||
TextLinesHint.Clear();
|
||||
TextLinesEncounter.Clear();
|
||||
|
||||
var hover = Main.Settings.Hover;
|
||||
var (before, mid, after) = GetBeforeAndAfter(pk, ctx, settings);
|
||||
|
||||
AppendTextSection(TextLinesPre, before, hover.PreviewShowPaste, ForeColor);
|
||||
BuildMoves(pk, ctx.Analysis, settings);
|
||||
AppendTextSection(TextLinesHint, mid, hover.HoverSlotShowLegalityHint, IllegalTextColor);
|
||||
AppendTextSection(TextLinesEncounter, after, hover.HoverSlotShowEncounter, ForeColor);
|
||||
|
||||
ApplySize();
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
private void BuildMoves(PKM pk, LegalityAnalysis la, in BattleTemplateExportSettings settings)
|
||||
{
|
||||
if (pk.MoveCount == 0)
|
||||
return;
|
||||
|
||||
var context = pk.Context;
|
||||
var strings = settings.Localization.Strings;
|
||||
var names = strings.movelist;
|
||||
var checks = la.Info.Moves;
|
||||
|
||||
AppendMoveLine(pk, strings, names, context, pk.Move1, checks[0].Valid);
|
||||
AppendMoveLine(pk, strings, names, context, pk.Move2, checks[1].Valid);
|
||||
AppendMoveLine(pk, strings, names, context, pk.Move3, checks[2].Valid);
|
||||
AppendMoveLine(pk, strings, names, context, pk.Move4, checks[3].Valid);
|
||||
}
|
||||
|
||||
private void AppendMoveLine(PKM pk, GameStrings strings, ReadOnlySpan<string> names, EntityContext context, ushort move, bool valid)
|
||||
{
|
||||
if (move == 0 || move >= names.Length)
|
||||
return;
|
||||
|
||||
byte type = MoveInfo.GetType(move, context);
|
||||
var name = names[move];
|
||||
if (move == (int)PKHeX.Core.Move.HiddenPower && pk.Context is not EntityContext.Gen8a)
|
||||
{
|
||||
if (HiddenPower.TryGetTypeIndex(pk.HPType, out type))
|
||||
name = $"{name} ({strings.types[type]}) [{pk.HPPower}]";
|
||||
}
|
||||
|
||||
var image = TypeSpriteUtil.GetTypeSpriteIconSmall(type);
|
||||
var color = valid ? ForeColor : IllegalTextColor;
|
||||
MoveLines.Add(new RenderMoveLine(name, image, color));
|
||||
}
|
||||
|
||||
private static void AppendTextSection(List<RenderTextLine> list, ReadOnlySpan<char> text, bool visible, Color color)
|
||||
{
|
||||
if (!visible || text.Length == 0)
|
||||
return;
|
||||
|
||||
int i = 0;
|
||||
var lines = text.EnumerateLines();
|
||||
foreach (var line in lines)
|
||||
{
|
||||
var topPadding = i == 0 ? TextSectionTopPadding : TextLineSpacing;
|
||||
const int bottomPadding = 0;
|
||||
list.Add(new RenderTextLine(line.ToString(), color, topPadding, bottomPadding));
|
||||
i++;
|
||||
}
|
||||
|
||||
var last = list[^1];
|
||||
list[^1] = last with { BottomPadding = TextSectionBottomPadding };
|
||||
}
|
||||
|
||||
private void ApplySize()
|
||||
{
|
||||
var width = GetPreferredWidth();
|
||||
var height = GetPreferredHeight();
|
||||
var size = new Size(width, height);
|
||||
if (Size != size)
|
||||
Size = size;
|
||||
}
|
||||
|
||||
private int GetPreferredWidth()
|
||||
{
|
||||
var width = 0;
|
||||
|
||||
var nameSize = MeasureSize(HeaderName, Font);
|
||||
var headerWidth = Border + HeaderLeftPadding + nameSize.Width + HeaderRightPadding + Border;
|
||||
if (HeaderBall != null)
|
||||
headerWidth += IconSize + HeaderIconGap;
|
||||
if (HeaderGender != null)
|
||||
headerWidth += IconSize + HeaderIconGap;
|
||||
|
||||
width = Math.Max(width, headerWidth);
|
||||
|
||||
foreach (var move in MoveLines)
|
||||
{
|
||||
var size = MeasureSize(move.Text, Font);
|
||||
var lineWidth = Border + BodyLeftPadding + IconSize + MoveIconTextGap + size.Width + BodyRightPadding + Border;
|
||||
width = Math.Max(width, lineWidth);
|
||||
}
|
||||
foreach (var line in TextLinesPre)
|
||||
{
|
||||
var size = MeasureSize(line.Text, Font);
|
||||
var lineWidth = Border + BodyLeftPadding + size.Width + BodyRightPadding + Border;
|
||||
width = Math.Max(width, lineWidth);
|
||||
}
|
||||
foreach (var line in TextLinesHint)
|
||||
{
|
||||
var size = MeasureSize(line.Text, Font);
|
||||
var lineWidth = Border + BodyLeftPadding + size.Width + BodyRightPadding + Border;
|
||||
width = Math.Max(width, lineWidth);
|
||||
}
|
||||
foreach (var line in TextLinesEncounter)
|
||||
{
|
||||
var size = MeasureSize(line.Text, Font);
|
||||
var lineWidth = Border + BodyLeftPadding + size.Width + BodyRightPadding + Border;
|
||||
width = Math.Max(width, lineWidth);
|
||||
}
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
private int GetPreferredHeight()
|
||||
{
|
||||
var height = Border;
|
||||
height += HeaderTopPadding + IconSize + HeaderBottomPadding;
|
||||
height += Border;
|
||||
|
||||
height += BodyTopPadding;
|
||||
|
||||
if (MoveLines.Count != 0)
|
||||
{
|
||||
height += MoveSectionTopPadding;
|
||||
height += MoveLines.Count * IconSize;
|
||||
height += MoveSectionBottomPadding;
|
||||
}
|
||||
|
||||
foreach (var line in TextLinesPre)
|
||||
{
|
||||
height += line.TopPadding;
|
||||
var textHeight = Math.Max(Font.Height, MeasureSize(line.Text, Font).Height);
|
||||
height += textHeight;
|
||||
height += line.BottomPadding;
|
||||
}
|
||||
foreach (var line in TextLinesHint)
|
||||
{
|
||||
height += line.TopPadding;
|
||||
var textHeight = Math.Max(Font.Height, MeasureSize(line.Text, Font).Height);
|
||||
height += textHeight;
|
||||
height += line.BottomPadding;
|
||||
}
|
||||
foreach (var line in TextLinesEncounter)
|
||||
{
|
||||
height += line.TopPadding;
|
||||
var textHeight = Math.Max(Font.Height, MeasureSize(line.Text, Font).Height);
|
||||
height += textHeight;
|
||||
height += line.BottomPadding;
|
||||
}
|
||||
|
||||
height += BodyBottomPadding;
|
||||
height += Border;
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
protected override void OnPaint(PaintEventArgs e)
|
||||
{
|
||||
base.OnPaint(e);
|
||||
|
||||
var g = e.Graphics;
|
||||
g.Clear(BackColor);
|
||||
|
||||
var outer = new Rectangle(0, 0, Width - 1, Height - 1);
|
||||
g.DrawRectangle(SystemPens.ControlDark, outer);
|
||||
|
||||
var headerTop = Border;
|
||||
var headerHeight = HeaderTopPadding + IconSize + HeaderBottomPadding;
|
||||
var headerBottom = headerTop + headerHeight;
|
||||
g.DrawLine(SystemPens.ControlDark, Border, headerBottom, Width - Border - 1, headerBottom);
|
||||
|
||||
DrawHeader(g, headerTop);
|
||||
|
||||
var y = headerBottom + BodyTopPadding;
|
||||
y = DrawTextLines(TextLinesPre, g, y);
|
||||
y = DrawMoves(g, y);
|
||||
y = DrawTextLines(TextLinesHint, g, y);
|
||||
|
||||
if (TextLinesEncounter.Count != 0)
|
||||
{
|
||||
g.DrawLine(SystemPens.ControlDark, Border, y, Width - Border - 1, y);
|
||||
y += Border;
|
||||
_ = DrawTextLines(TextLinesEncounter, g, y);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawHeader(Graphics g, int headerTop)
|
||||
{
|
||||
var y = headerTop + HeaderTopPadding;
|
||||
var x = Border + HeaderLeftPadding;
|
||||
|
||||
if (HeaderBall is not null)
|
||||
{
|
||||
g.DrawImage(HeaderBall, new Rectangle(x, y, IconSize, IconSize));
|
||||
x += IconSize + HeaderIconGap;
|
||||
}
|
||||
|
||||
var textRect = new Rectangle(x, y, Math.Max(0, Width - x - Border - HeaderRightPadding - IconSize - HeaderIconGap), IconSize);
|
||||
TextRenderer.DrawText(g, HeaderName, Font, textRect, ForeColor, TextFormatFlags.Left | TextFormatFlags.VerticalCenter | TextFormatFlags.EndEllipsis | TextFormatFlags.NoPadding);
|
||||
|
||||
// Gender displayed at right edge.
|
||||
if (HeaderGender is not null)
|
||||
{
|
||||
var genderX = Width - Border - HeaderRightPadding - IconSize;
|
||||
g.DrawImage(HeaderGender, new Rectangle(genderX, y, IconSize, IconSize));
|
||||
}
|
||||
}
|
||||
|
||||
private int DrawMoves(Graphics g, int y)
|
||||
{
|
||||
if (MoveLines.Count == 0)
|
||||
return y;
|
||||
|
||||
const int x = Border + BodyLeftPadding;
|
||||
y += MoveSectionTopPadding;
|
||||
foreach (var line in MoveLines)
|
||||
{
|
||||
if (line.Icon is not null)
|
||||
g.DrawImage(line.Icon, new Rectangle(x, y, IconSize, IconSize));
|
||||
|
||||
var textRect = new Rectangle(x + IconSize + MoveIconTextGap, y, Math.Max(0, Width - (x + IconSize + MoveIconTextGap) - Border - BodyRightPadding), IconSize);
|
||||
TextRenderer.DrawText(g, line.Text, Font, textRect, line.Color, TextFormatFlags.Left | TextFormatFlags.VerticalCenter | TextFormatFlags.NoPadding);
|
||||
y += IconSize;
|
||||
}
|
||||
y += MoveSectionBottomPadding;
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
private int DrawTextLines(List<RenderTextLine> list, Graphics g, int y)
|
||||
{
|
||||
const int x = Border + BodyLeftPadding;
|
||||
var textWidth = Math.Max(0, Width - x - Border - BodyRightPadding);
|
||||
|
||||
foreach (var line in list)
|
||||
{
|
||||
y += line.TopPadding;
|
||||
var height = Math.Max(Font.Height, MeasureSize(line.Text, Font).Height);
|
||||
var rect = new Rectangle(x, y, textWidth, height);
|
||||
TextRenderer.DrawText(g, line.Text, Font, rect, line.Color, TextFormatFlags.Left | TextFormatFlags.NoPadding);
|
||||
y += height + line.BottomPadding;
|
||||
}
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
public static Size MeasureSize(ReadOnlySpan<char> text, Font font)
|
||||
{
|
||||
const TextFormatFlags flags = TextFormatFlags.LeftAndRightPadding | TextFormatFlags.VerticalCenter;
|
||||
return TextRenderer.MeasureText(text, font, new Size(), flags);
|
||||
}
|
||||
|
||||
private static string GetNameTitle(PKM pk, in BattleTemplateExportSettings settings)
|
||||
{
|
||||
// Don't care about form; the user will be able to see the sprite next to the preview.
|
||||
var nick = pk.Nickname;
|
||||
var strings = settings.Localization.Strings;
|
||||
var all = strings.Species;
|
||||
|
|
@ -61,85 +342,30 @@ private static string GetNameTitle(PKM pk, in BattleTemplateExportSettings setti
|
|||
return nick;
|
||||
var expect = all[species];
|
||||
if (settings.IsTokenInExport(BattleTemplateToken.Nickname))
|
||||
return expect; // Nickname will be on another line.
|
||||
return expect;
|
||||
|
||||
if (nick.Equals(expect, StringComparison.OrdinalIgnoreCase))
|
||||
return nick;
|
||||
return $"{nick} ({expect})";
|
||||
}
|
||||
|
||||
private void PopulateBall(PKM pk)
|
||||
private static Image GetBallImage(PKM pk)
|
||||
{
|
||||
var ball = (byte)Ball.Poke;
|
||||
if (pk.Format >= 3)
|
||||
ball = pk.Ball;
|
||||
PB_Ball.Image = Drawing.PokeSprite.SpriteUtil.GetBallSprite(ball);
|
||||
return SpriteUtil.GetBallSprite(ball);
|
||||
}
|
||||
|
||||
private void PopulateGender(PKM pk)
|
||||
private static Image? GetGenderImage(PKM pk)
|
||||
{
|
||||
if (pk.Format == 1)
|
||||
{
|
||||
PB_Gender.Image = null;
|
||||
return;
|
||||
}
|
||||
return null;
|
||||
|
||||
var gender = pk.Gender;
|
||||
if (gender >= GenderImages.Length)
|
||||
gender = 2;
|
||||
PB_Gender.Image = GenderImages[gender];
|
||||
}
|
||||
|
||||
private void PopulateMoves(PKM pk, LegalityAnalysis la, in BattleTemplateExportSettings settings, ref int width)
|
||||
{
|
||||
var context = pk.Context;
|
||||
var strings = settings.Localization.Strings;
|
||||
var names = strings.movelist;
|
||||
var check = la.Info.Moves;
|
||||
var w1 = Move1.Populate(pk, strings, pk.Move1, context, names, check[0].Valid);
|
||||
var w2 = Move2.Populate(pk, strings, pk.Move2, context, names, check[1].Valid);
|
||||
var w3 = Move3.Populate(pk, strings, pk.Move3, context, names, check[2].Valid);
|
||||
var w4 = Move4.Populate(pk, strings, pk.Move4, context, names, check[3].Valid);
|
||||
|
||||
var maxWidth = Math.Max(w1, Math.Max(w2, Math.Max(w3, w4)));
|
||||
width = Math.Max(width, maxWidth + Move1.Margin.Horizontal + interiorMargin);
|
||||
}
|
||||
|
||||
private void PopulateText(PKM pk, in LegalityLocalizationContext la, in BattleTemplateExportSettings settings, int width)
|
||||
{
|
||||
var (before, mid, after) = GetBeforeAndAfter(pk, la, settings);
|
||||
var hover = Main.Settings.Hover;
|
||||
|
||||
bool hasMoves = pk.MoveCount != 0;
|
||||
FLP_Moves.Visible = hasMoves;
|
||||
var height = FLP_List.Top + interiorMargin;
|
||||
if (hasMoves)
|
||||
height += FLP_Moves.Height + FLP_Moves.Margin.Vertical;
|
||||
ToggleLabel(L_LinesBeforeMoves, before, hover.PreviewShowPaste, ref width, ref height);
|
||||
ToggleLabel(L_HintIllegal, mid, hover.HoverSlotShowLegalityHint, ref width, ref height);
|
||||
ToggleLabel(L_LinesAfterMoves, after, hover.HoverSlotShowEncounter, ref width, ref height);
|
||||
Size = new Size(width, height);
|
||||
}
|
||||
|
||||
private static void ToggleLabel(Control display, string text, bool visible, ref int width, ref int height)
|
||||
{
|
||||
if (!visible || text.Length == 0)
|
||||
{
|
||||
display.Visible = false;
|
||||
return;
|
||||
}
|
||||
|
||||
var size = MeasureSize(text, display.Font);
|
||||
width = Math.Max(width, display.Margin.Horizontal + size.Width);
|
||||
height += size.Height + display.Margin.Vertical;
|
||||
display.Text = text;
|
||||
display.Visible = true;
|
||||
}
|
||||
|
||||
public static Size MeasureSize(ReadOnlySpan<char> text, Font font)
|
||||
{
|
||||
const TextFormatFlags flags = TextFormatFlags.LeftAndRightPadding | TextFormatFlags.VerticalCenter;
|
||||
return TextRenderer.MeasureText(text, font, new Size(), flags);
|
||||
return GenderImages[gender];
|
||||
}
|
||||
|
||||
private static (string Before, string Middle, string After) GetBeforeAndAfter(PKM pk, in LegalityLocalizationContext la, in BattleTemplateExportSettings settings)
|
||||
|
|
@ -218,4 +444,7 @@ protected override CreateParams CreateParams
|
|||
return createParams;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly record struct RenderMoveLine(string Text, Image? Icon, Color Color);
|
||||
private readonly record struct RenderTextLine(string Text, Color Color, int TopPadding, int BottomPadding);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,11 @@ public void Show(Control pb, PKM pk, StorageSlotType type = StorageSlotType.None
|
|||
else if (Settings.HoverSlotShowText)
|
||||
{
|
||||
var text = GetPreviewText(pk, settings);
|
||||
if (!settings.Order.Contains(BattleTemplateToken.FirstLine))
|
||||
{
|
||||
var insert = GetPreviewText(pk, settings with { Order = [BattleTemplateToken.FirstLine] });
|
||||
text = insert + Environment.NewLine + text;
|
||||
}
|
||||
if (Settings.HoverSlotShowEncounter)
|
||||
text = AppendEncounterInfo(ctx, text);
|
||||
ShowSet.SetToolTip(pb, text);
|
||||
|
|
@ -52,9 +57,11 @@ private void UpdatePreview(Control pb, PKM pk, in BattleTemplateExportSettings s
|
|||
_source.Cancel();
|
||||
_source.Dispose(); // Properly dispose the previous CancellationTokenSource
|
||||
_source = new();
|
||||
var wasVisible = Previewer.Visible;
|
||||
UpdatePreviewPosition(new());
|
||||
Previewer.Populate(pk, settings, ctx);
|
||||
ShowInactiveTopmost(Previewer);
|
||||
if (!wasVisible)
|
||||
ShowInactiveTopmost(Previewer);
|
||||
}
|
||||
|
||||
private const int SW_SHOWNOACTIVATE = 4;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user