439 lines
15 KiB
C#
439 lines
15 KiB
C#
using PluginLoader.Data;
|
|
using PluginLoader.GUI.GuiControls;
|
|
using PluginLoader.Stats;
|
|
using PluginLoader.Stats.Model;
|
|
using Sandbox.Graphics.GUI;
|
|
using VRage.Game;
|
|
using VRage.Utils;
|
|
using VRageMath;
|
|
|
|
namespace PluginLoader.GUI;
|
|
|
|
public class PluginDetailsPanel : MyGuiControlParent
|
|
{
|
|
private readonly PluginStat dummyStat = new();
|
|
|
|
private readonly MyGuiScreenPluginConfig pluginsDialog;
|
|
private MyGuiControlLabel authorLabel;
|
|
private MyGuiControlLabel authorText;
|
|
private MyGuiControlButton configButton;
|
|
private MyGuiControlCompositePanel descriptionPanel;
|
|
private MyGuiControlMultilineText descriptionText;
|
|
private MyGuiControlButton downvoteButton;
|
|
private MyGuiControlLabel downvoteCountText;
|
|
private MyGuiControlImage downvoteIcon;
|
|
private MyGuiControlCheckbox enableCheckbox;
|
|
private MyGuiControlLabel enableLabel;
|
|
private MyGuiControlButton infoButton;
|
|
private PluginInstance instance;
|
|
|
|
// Layout management
|
|
private MyLayoutTable layoutTable;
|
|
|
|
// Plugin currently loaded into the panel or null if none are loaded
|
|
private PluginData plugin;
|
|
|
|
// Panel controls
|
|
private MyGuiControlLabel pluginNameLabel;
|
|
private MyGuiControlLabel pluginNameText;
|
|
private RatingControl ratingControl;
|
|
private MyGuiControlLabel ratingLabel;
|
|
private MyGuiControlLabel statusLabel;
|
|
private MyGuiControlLabel statusText;
|
|
private MyGuiControlButton upvoteButton;
|
|
private MyGuiControlLabel upvoteCountText;
|
|
private MyGuiControlImage upvoteIcon;
|
|
private MyGuiControlLabel usageLabel;
|
|
private MyGuiControlLabel usageText;
|
|
private MyGuiControlLabel versionLabel;
|
|
private MyGuiControlLabel versionText;
|
|
|
|
public PluginDetailsPanel(MyGuiScreenPluginConfig dialog)
|
|
{
|
|
pluginsDialog = dialog;
|
|
}
|
|
|
|
public PluginData Plugin
|
|
{
|
|
get => plugin;
|
|
set
|
|
{
|
|
if (ReferenceEquals(value, Plugin))
|
|
return;
|
|
|
|
plugin = value;
|
|
|
|
if (plugin == null)
|
|
{
|
|
DisableControls();
|
|
ClearPluginData();
|
|
return;
|
|
}
|
|
|
|
if (Main.Instance.TryGetPluginInstance(plugin.Id, out var instance))
|
|
this.instance = instance;
|
|
else
|
|
this.instance = null;
|
|
|
|
EnableControls();
|
|
LoadPluginData();
|
|
}
|
|
}
|
|
|
|
private PluginStat PluginStat => pluginsDialog.PluginStats?.Stats.GetValueOrDefault(plugin.Id) ?? dummyStat;
|
|
public event Action<PluginData, bool> OnPluginToggled;
|
|
|
|
private void DisableControls()
|
|
{
|
|
foreach (var control in Controls)
|
|
control.Enabled = false;
|
|
}
|
|
|
|
private void EnableControls()
|
|
{
|
|
foreach (var control in Controls)
|
|
control.Enabled = true;
|
|
}
|
|
|
|
private void ClearPluginData()
|
|
{
|
|
pluginNameText.Text = "";
|
|
authorText.Text = "";
|
|
versionText.Text = "";
|
|
statusText.Text = "";
|
|
usageText.Text = "";
|
|
ratingControl.Value = 0;
|
|
upvoteButton.Checked = false;
|
|
downvoteButton.Checked = false;
|
|
descriptionText.Text.Clear();
|
|
enableCheckbox.IsChecked = false;
|
|
}
|
|
|
|
public void LoadPluginData()
|
|
{
|
|
if (plugin == null)
|
|
return;
|
|
|
|
var stat = PluginStat;
|
|
var vote = stat.Vote;
|
|
var nonLocal = !plugin.IsLocal;
|
|
var canVote = (plugin.Enabled || stat.Tried) && nonLocal;
|
|
var showVotes = canVote || nonLocal;
|
|
|
|
pluginNameText.Text = plugin.FriendlyName ?? "N/A";
|
|
|
|
authorText.Text = plugin.Author ?? (plugin.IsLocal ? "Local" : "N/A");
|
|
|
|
versionText.Text = plugin.Version?.ToString() ?? "N/A";
|
|
|
|
statusLabel.Visible = nonLocal;
|
|
statusText.Visible = nonLocal;
|
|
statusText.Text = plugin.Status == PluginStatus.None
|
|
? plugin.Enabled ? "Up to date" : "N/A"
|
|
: plugin.StatusString;
|
|
|
|
usageLabel.Visible = nonLocal;
|
|
usageText.Visible = nonLocal;
|
|
usageText.Text = stat.Players.ToString();
|
|
|
|
ratingLabel.Visible = showVotes;
|
|
|
|
upvoteIcon.Visible = showVotes;
|
|
upvoteButton.Visible = canVote;
|
|
upvoteButton.Checked = vote > 0;
|
|
upvoteCountText.Visible = showVotes;
|
|
upvoteCountText.Text = $"{stat.Upvotes}";
|
|
|
|
downvoteIcon.Visible = showVotes;
|
|
downvoteButton.Visible = canVote;
|
|
downvoteButton.Checked = vote < 0;
|
|
downvoteCountText.Visible = showVotes;
|
|
downvoteCountText.Text = $"{stat.Downvotes}";
|
|
|
|
ratingControl.Value = stat.Rating;
|
|
|
|
plugin.GetDescriptionText(descriptionText);
|
|
descriptionPanel.Visible = descriptionText.Visible;
|
|
|
|
enableCheckbox.IsChecked = pluginsDialog.AfterRebootEnableFlags[plugin.Id];
|
|
|
|
configButton.Enabled = instance != null && instance.HasConfigDialog;
|
|
configButton.Visible = instance != null;
|
|
}
|
|
|
|
public virtual void CreateControls(Vector2 rightSideOrigin)
|
|
{
|
|
// Plugin name
|
|
pluginNameLabel = new()
|
|
{
|
|
Text = "Name",
|
|
OriginAlign = MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_TOP
|
|
};
|
|
pluginNameText = new()
|
|
{
|
|
OriginAlign = MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_TOP
|
|
};
|
|
|
|
// Author
|
|
authorLabel = new()
|
|
{
|
|
Text = "Author",
|
|
OriginAlign = MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_TOP
|
|
};
|
|
authorText = new()
|
|
{
|
|
OriginAlign = MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_TOP
|
|
};
|
|
|
|
// Version
|
|
versionLabel = new()
|
|
{
|
|
Text = "Version",
|
|
OriginAlign = MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_TOP
|
|
};
|
|
versionText = new()
|
|
{
|
|
OriginAlign = MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_TOP
|
|
};
|
|
|
|
// Status
|
|
statusLabel = new()
|
|
{
|
|
Text = "Status",
|
|
OriginAlign = MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_TOP
|
|
};
|
|
statusText = new()
|
|
{
|
|
OriginAlign = MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_TOP
|
|
};
|
|
|
|
// Usage
|
|
usageLabel = new()
|
|
{
|
|
Text = "Usage",
|
|
OriginAlign = MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_TOP
|
|
};
|
|
usageText = new()
|
|
{
|
|
OriginAlign = MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_TOP
|
|
};
|
|
|
|
// Rating
|
|
ratingLabel = new()
|
|
{
|
|
Text = "Rating",
|
|
OriginAlign = MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_TOP
|
|
};
|
|
|
|
upvoteButton = new(null, MyGuiControlButtonStyleEnum.Rectangular, onButtonClick: OnRateUpClicked,
|
|
size: new Vector2(0.03f))
|
|
{
|
|
CanHaveFocus = false
|
|
};
|
|
upvoteIcon = CreateRateIcon(upvoteButton, "Textures\\GUI\\Icons\\Blueprints\\like_test.png");
|
|
upvoteIcon.CanHaveFocus = false;
|
|
upvoteCountText = new()
|
|
{
|
|
OriginAlign = MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_TOP
|
|
};
|
|
|
|
downvoteButton = new(null, MyGuiControlButtonStyleEnum.Rectangular, onButtonClick: OnRateDownClicked,
|
|
size: new Vector2(0.03f))
|
|
{
|
|
CanHaveFocus = false
|
|
};
|
|
downvoteIcon = CreateRateIcon(downvoteButton, "Textures\\GUI\\Icons\\Blueprints\\dislike_test.png");
|
|
downvoteIcon.CanHaveFocus = false;
|
|
downvoteCountText = new()
|
|
{
|
|
OriginAlign = MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_TOP
|
|
};
|
|
|
|
ratingControl = new()
|
|
{
|
|
OriginAlign = MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_TOP,
|
|
Visible = false // FIXME: Make the rating (stars) visible later! Its positioning should already be good.
|
|
};
|
|
|
|
// Plugin description
|
|
descriptionText = new()
|
|
{
|
|
Name = "DescriptionText",
|
|
OriginAlign = MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_TOP,
|
|
TextAlign = MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_TOP,
|
|
TextBoxAlign = MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_TOP
|
|
};
|
|
descriptionText.OnLinkClicked += (x, url) => MyGuiSandbox.OpenUrl(url, UrlOpenMode.SteamOrExternalWithConfirm);
|
|
descriptionPanel = new()
|
|
{
|
|
BackgroundTexture = MyGuiConstants.TEXTURE_RECTANGLE_DARK_BORDER
|
|
};
|
|
|
|
// Enable checkbox
|
|
enableLabel = new()
|
|
{
|
|
Text = "Enabled",
|
|
OriginAlign = MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_TOP
|
|
};
|
|
enableCheckbox = new(toolTip: "Enables loading the plugin when SE is started.")
|
|
{
|
|
OriginAlign = MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_TOP,
|
|
Enabled = false
|
|
};
|
|
enableCheckbox.IsCheckedChanged += TogglePlugin;
|
|
|
|
// Info button
|
|
infoButton = new(onButtonClick: _ => Plugin?.Show())
|
|
{
|
|
OriginAlign = MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_TOP,
|
|
Text = "Plugin Info"
|
|
};
|
|
|
|
// Plugin config button
|
|
configButton = new(onButtonClick: _ => instance?.OpenConfig())
|
|
{
|
|
OriginAlign = MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_TOP,
|
|
Text = "Plugin Config"
|
|
};
|
|
|
|
LayoutControls(rightSideOrigin);
|
|
}
|
|
|
|
private void LayoutControls(Vector2 rightSideOrigin)
|
|
{
|
|
layoutTable = new(this, rightSideOrigin, new(1f, 1f));
|
|
layoutTable.SetColumnWidths(168f, 468f);
|
|
layoutTable.SetRowHeights(60f, 60f, 60f, 60f, 60f, 60f, 420f, 60f, 60f);
|
|
|
|
var row = 0;
|
|
|
|
layoutTable.Add(pluginNameLabel, MyAlignH.Left, MyAlignV.Center, row, 0);
|
|
layoutTable.Add(pluginNameText, MyAlignH.Left, MyAlignV.Center, row, 1);
|
|
row++;
|
|
|
|
layoutTable.Add(authorLabel, MyAlignH.Left, MyAlignV.Center, row, 0);
|
|
layoutTable.Add(authorText, MyAlignH.Left, MyAlignV.Center, row, 1);
|
|
row++;
|
|
|
|
layoutTable.Add(versionLabel, MyAlignH.Left, MyAlignV.Center, row, 0);
|
|
layoutTable.Add(versionText, MyAlignH.Left, MyAlignV.Center, row, 1);
|
|
row++;
|
|
|
|
layoutTable.Add(statusLabel, MyAlignH.Left, MyAlignV.Center, row, 0);
|
|
layoutTable.Add(statusText, MyAlignH.Left, MyAlignV.Center, row, 1);
|
|
row++;
|
|
|
|
layoutTable.Add(usageLabel, MyAlignH.Left, MyAlignV.Center, row, 0);
|
|
layoutTable.Add(usageText, MyAlignH.Left, MyAlignV.Center, row, 1);
|
|
row++;
|
|
|
|
layoutTable.Add(ratingLabel, MyAlignH.Left, MyAlignV.Center, row, 0);
|
|
layoutTable.Add(upvoteCountText, MyAlignH.Left, MyAlignV.Center, row, 1);
|
|
layoutTable.Add(upvoteButton, MyAlignH.Left, MyAlignV.Center, row, 1);
|
|
layoutTable.Add(upvoteIcon, MyAlignH.Left, MyAlignV.Center, row, 1);
|
|
layoutTable.Add(downvoteCountText, MyAlignH.Left, MyAlignV.Center, row, 1);
|
|
layoutTable.Add(downvoteButton, MyAlignH.Left, MyAlignV.Center, row, 1);
|
|
layoutTable.Add(downvoteIcon, MyAlignH.Left, MyAlignV.Center, row, 1);
|
|
layoutTable.Add(ratingControl, MyAlignH.Left, MyAlignV.Center, row, 1);
|
|
|
|
const float counterWidth = 0.05f;
|
|
const float spacing = 0.005f;
|
|
var buttonWidth = upvoteButton.Size.X;
|
|
var voteWidth = buttonWidth + spacing + counterWidth + 3 * spacing;
|
|
var buttonToIconOffset = new Vector2(0.004f, -0.001f);
|
|
upvoteIcon.Position = upvoteButton.Position + buttonToIconOffset;
|
|
upvoteCountText.Position = upvoteButton.Position + new Vector2(buttonWidth + spacing, 0f);
|
|
downvoteButton.Position = upvoteButton.Position + new Vector2(voteWidth, 0f);
|
|
downvoteIcon.Position = downvoteButton.Position + buttonToIconOffset;
|
|
downvoteCountText.Position = downvoteButton.Position + new Vector2(buttonWidth + spacing, 0f);
|
|
ratingControl.Position = downvoteButton.Position + new Vector2(voteWidth, 0f);
|
|
row++;
|
|
|
|
layoutTable.AddWithSize(descriptionPanel, MyAlignH.Center, MyAlignV.Top, row, 0, 1, 2);
|
|
layoutTable.AddWithSize(descriptionText, MyAlignH.Center, MyAlignV.Center, row, 0, 1, 2);
|
|
row++;
|
|
|
|
layoutTable.Add(enableLabel, MyAlignH.Left, MyAlignV.Center, row, 0);
|
|
layoutTable.Add(enableCheckbox, MyAlignH.Left, MyAlignV.Center, row, 1);
|
|
row++;
|
|
|
|
const float infoConfigSpacing = 0.015f;
|
|
layoutTable.AddWithSize(infoButton, MyAlignH.Right, MyAlignV.Center, row, 0, 1, 2);
|
|
layoutTable.AddWithSize(configButton, MyAlignH.Right, MyAlignV.Center, row, 0, 1, 2);
|
|
configButton.Position += new Vector2(0f, infoConfigSpacing);
|
|
infoButton.Position = configButton.Position + new Vector2(-configButton.Size.X - infoConfigSpacing, 0);
|
|
// row++;
|
|
|
|
var border = 0.002f * Vector2.One;
|
|
descriptionPanel.Position -= border;
|
|
descriptionPanel.Size += 2 * border;
|
|
|
|
DisableControls();
|
|
}
|
|
|
|
private void TogglePlugin(MyGuiControlCheckbox obj)
|
|
{
|
|
if (plugin == null)
|
|
return;
|
|
|
|
OnPluginToggled?.Invoke(plugin, enableCheckbox.IsChecked);
|
|
}
|
|
|
|
private void OnRateUpClicked(MyGuiControlButton button)
|
|
{
|
|
Vote(1);
|
|
}
|
|
|
|
private void OnRateDownClicked(MyGuiControlButton button)
|
|
{
|
|
Vote(-1);
|
|
}
|
|
|
|
private void Vote(int vote)
|
|
{
|
|
if (PlayerConsent.ConsentGiven)
|
|
StoreVote(vote);
|
|
else
|
|
PlayerConsent.ShowDialog(() => StoreVote(vote));
|
|
}
|
|
|
|
private void StoreVote(int vote)
|
|
{
|
|
if (!PlayerConsent.ConsentGiven || pluginsDialog.PluginStats == null)
|
|
return;
|
|
|
|
var originalStat = PluginStat;
|
|
if (originalStat.Vote == vote)
|
|
vote = 0;
|
|
|
|
var updatedStat = StatsClient.Vote(plugin.Id, vote);
|
|
if (updatedStat == null)
|
|
return;
|
|
|
|
pluginsDialog.PluginStats.Stats[plugin.Id] = updatedStat;
|
|
LoadPluginData();
|
|
}
|
|
|
|
// From Sandbox.Game.Screens.MyGuiScreenNewWorkshopGame
|
|
|
|
#region Vote buttons
|
|
|
|
private MyGuiControlImage CreateRateIcon(MyGuiControlButton button, string texture)
|
|
{
|
|
var myGuiControlImage = new MyGuiControlImage(null, null, null, null, new[] { texture });
|
|
AdjustButtonForIcon(button, myGuiControlImage);
|
|
myGuiControlImage.Size = button.Size * 0.6f;
|
|
return myGuiControlImage;
|
|
}
|
|
|
|
private void AdjustButtonForIcon(MyGuiControlButton button, MyGuiControlImage icon)
|
|
{
|
|
button.Size = new(button.Size.X, button.Size.X * 4f / 3f);
|
|
button.HighlightChanged += delegate(MyGuiControlBase control)
|
|
{
|
|
icon.ColorMask = control.HasHighlight ? MyGuiConstants.HIGHLIGHT_TEXT_COLOR : Vector4.One;
|
|
};
|
|
}
|
|
|
|
#endregion
|
|
} |