mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-16 13:44:17 +01:00
209 lines
No EOL
7.9 KiB
C#
209 lines
No EOL
7.9 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.Numerics;
|
|
using Dalamud.Interface;
|
|
using Dalamud.Interface.GameFonts;
|
|
using ImGuiNET;
|
|
using OtterGui;
|
|
using OtterGui.Raii;
|
|
using Penumbra.UI.Classes;
|
|
|
|
namespace Penumbra.UI;
|
|
|
|
public partial class ConfigWindow
|
|
{
|
|
private partial class ModPanel
|
|
{
|
|
// We use a big, nice game font for the title.
|
|
private readonly GameFontHandle _nameFont =
|
|
Dalamud.PluginInterface.UiBuilder.GetGameFontHandle( new GameFontStyle( GameFontFamilyAndSize.Jupiter23 ) );
|
|
|
|
// Header data.
|
|
private string _modName = string.Empty;
|
|
private string _modAuthor = string.Empty;
|
|
private string _modVersion = string.Empty;
|
|
private string _modWebsite = string.Empty;
|
|
private string _modWebsiteButton = string.Empty;
|
|
private bool _websiteValid;
|
|
|
|
private float _modNameWidth;
|
|
private float _modAuthorWidth;
|
|
private float _modVersionWidth;
|
|
private float _modWebsiteButtonWidth;
|
|
private float _secondRowWidth;
|
|
|
|
// Draw the header for the current mod,
|
|
// consisting of its name, version, author and website, if they exist.
|
|
private void DrawModHeader()
|
|
{
|
|
var offset = DrawModName();
|
|
DrawVersion( offset );
|
|
DrawSecondRow( offset );
|
|
}
|
|
|
|
// Draw the mod name in the game font with a 2px border, centered,
|
|
// with at least the width of the version space to each side.
|
|
private float DrawModName()
|
|
{
|
|
var decidingWidth = Math.Max( _secondRowWidth, ImGui.GetWindowWidth() );
|
|
var offsetWidth = ( decidingWidth - _modNameWidth ) / 2;
|
|
var offsetVersion = _modVersion.Length > 0
|
|
? _modVersionWidth + ImGui.GetStyle().ItemSpacing.X + ImGui.GetStyle().WindowPadding.X
|
|
: 0;
|
|
var offset = Math.Max( offsetWidth, offsetVersion );
|
|
if( offset > 0 )
|
|
{
|
|
ImGui.SetCursorPosX( offset );
|
|
}
|
|
|
|
using var color = ImRaii.PushColor( ImGuiCol.Border, Colors.MetaInfoText );
|
|
using var style = ImRaii.PushStyle( ImGuiStyleVar.FrameBorderSize, 2 * ImGuiHelpers.GlobalScale );
|
|
using var font = ImRaii.PushFont( _nameFont.ImFont, _nameFont.Available );
|
|
ImGuiUtil.DrawTextButton( _modName, Vector2.Zero, 0 );
|
|
return offset;
|
|
}
|
|
|
|
// Draw the version in the top-right corner.
|
|
private void DrawVersion( float offset )
|
|
{
|
|
var oldPos = ImGui.GetCursorPos();
|
|
ImGui.SetCursorPos( new Vector2( 2 * offset + _modNameWidth - _modVersionWidth - ImGui.GetStyle().WindowPadding.X,
|
|
ImGui.GetStyle().FramePadding.Y ) );
|
|
ImGuiUtil.TextColored( Colors.MetaInfoText, _modVersion );
|
|
ImGui.SetCursorPos( oldPos );
|
|
}
|
|
|
|
// Draw author and website if they exist. The website is a button if it is valid.
|
|
// Usually, author begins at the left boundary of the name,
|
|
// and website ends at the right boundary of the name.
|
|
// If their combined width is larger than the name, they are combined-centered.
|
|
private void DrawSecondRow( float offset )
|
|
{
|
|
if( _modAuthor.Length == 0 )
|
|
{
|
|
if( _modWebsiteButton.Length == 0 )
|
|
{
|
|
ImGui.NewLine();
|
|
return;
|
|
}
|
|
|
|
offset += ( _modNameWidth - _modWebsiteButtonWidth ) / 2;
|
|
ImGui.SetCursorPosX( offset );
|
|
DrawWebsite();
|
|
}
|
|
else if( _modWebsiteButton.Length == 0 )
|
|
{
|
|
offset += ( _modNameWidth - _modAuthorWidth ) / 2;
|
|
ImGui.SetCursorPosX( offset );
|
|
DrawAuthor();
|
|
}
|
|
else if( _secondRowWidth < _modNameWidth )
|
|
{
|
|
ImGui.SetCursorPosX( offset );
|
|
DrawAuthor();
|
|
ImGui.SameLine( offset + _modNameWidth - _modWebsiteButtonWidth );
|
|
DrawWebsite();
|
|
}
|
|
else
|
|
{
|
|
offset -= ( _secondRowWidth - _modNameWidth ) / 2;
|
|
if( offset > 0 )
|
|
{
|
|
ImGui.SetCursorPosX( offset );
|
|
}
|
|
|
|
DrawAuthor();
|
|
ImGui.SameLine();
|
|
DrawWebsite();
|
|
}
|
|
}
|
|
|
|
// Draw the author text.
|
|
private void DrawAuthor()
|
|
{
|
|
using var style = ImRaii.PushStyle( ImGuiStyleVar.ItemSpacing, Vector2.Zero );
|
|
ImGuiUtil.TextColored( Colors.MetaInfoText, "by " );
|
|
ImGui.SameLine();
|
|
style.Pop();
|
|
ImGui.TextUnformatted( _mod.Author );
|
|
}
|
|
|
|
// Draw either a website button if the source is a valid website address,
|
|
// or a source text if it is not.
|
|
private void DrawWebsite()
|
|
{
|
|
if( _websiteValid )
|
|
{
|
|
if( ImGui.SmallButton( _modWebsiteButton ) )
|
|
{
|
|
try
|
|
{
|
|
var process = new ProcessStartInfo( _modWebsite )
|
|
{
|
|
UseShellExecute = true,
|
|
};
|
|
Process.Start( process );
|
|
}
|
|
catch
|
|
{
|
|
// ignored
|
|
}
|
|
}
|
|
|
|
ImGuiUtil.HoverTooltip( _modWebsite );
|
|
}
|
|
else
|
|
{
|
|
using var style = ImRaii.PushStyle( ImGuiStyleVar.ItemSpacing, Vector2.Zero );
|
|
ImGuiUtil.TextColored( Colors.MetaInfoText, "from " );
|
|
ImGui.SameLine();
|
|
style.Pop();
|
|
ImGui.TextUnformatted( _mod.Website );
|
|
}
|
|
}
|
|
|
|
// Update all mod header data. Should someone change frame padding or item spacing,
|
|
// or his default font, this will break, but he will just have to select a different mod to restore.
|
|
private void UpdateModData()
|
|
{
|
|
// Name
|
|
var name = $" {_mod.Name} ";
|
|
if( name != _modName )
|
|
{
|
|
using var font = ImRaii.PushFont( _nameFont.ImFont, _nameFont.Available );
|
|
_modName = name;
|
|
_modNameWidth = ImGui.CalcTextSize( name ).X + 2 * ( ImGui.GetStyle().FramePadding.X + 2 * ImGuiHelpers.GlobalScale );
|
|
}
|
|
|
|
// Author
|
|
var author = _mod.Author.IsEmpty ? string.Empty : $"by {_mod.Author}";
|
|
if( author != _modAuthor )
|
|
{
|
|
_modAuthor = author;
|
|
_modAuthorWidth = ImGui.CalcTextSize( author ).X;
|
|
_secondRowWidth = _modAuthorWidth + _modWebsiteButtonWidth + ImGui.GetStyle().ItemSpacing.X;
|
|
}
|
|
|
|
// Version
|
|
var version = _mod.Version.Length > 0 ? $"({_mod.Version})" : string.Empty;
|
|
if( version != _modVersion )
|
|
{
|
|
_modVersion = version;
|
|
_modVersionWidth = ImGui.CalcTextSize( version ).X;
|
|
}
|
|
|
|
// Website
|
|
if( _modWebsite != _mod.Website )
|
|
{
|
|
_modWebsite = _mod.Website;
|
|
_websiteValid = Uri.TryCreate( _modWebsite, UriKind.Absolute, out var uriResult )
|
|
&& ( uriResult.Scheme == Uri.UriSchemeHttps || uriResult.Scheme == Uri.UriSchemeHttp );
|
|
_modWebsiteButton = _websiteValid ? "Open Website" : _modWebsite.Length == 0 ? string.Empty : $"from {_modWebsite}";
|
|
_modWebsiteButtonWidth = _websiteValid
|
|
? ImGui.CalcTextSize( _modWebsiteButton ).X + 2 * ImGui.GetStyle().FramePadding.X
|
|
: ImGui.CalcTextSize( _modWebsiteButton ).X;
|
|
_secondRowWidth = _modAuthorWidth + _modWebsiteButtonWidth + ImGui.GetStyle().ItemSpacing.X;
|
|
}
|
|
}
|
|
}
|
|
} |