2using System.Collections.Generic;
6using HeathenEngineering.SteamworksIntegration;
8using UnityEngine.EventSystems;
19 public ModPreview.PreviewType
kind;
22 private sealed
class HoverRelay : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler
32 private const string urlWorkshopItem =
"https://steamcommunity.com/sharedfiles/filedetails/?id=";
102 private readonly Dictionary<BaseModPackage, string>
searchCache =
new Dictionary<BaseModPackage, string>();
104 private readonly Dictionary<BaseModPackage, PreviewEntry>
previews =
new Dictionary<BaseModPackage, PreviewEntry>();
123 int num = items.IndexOf(p);
124 if (num < 0 || num + a < 0 || num + a >= items.Count)
136 List<BaseModPackage> packages =
manager.packages;
137 int num = packages.IndexOf(p);
138 int num2 = ((target ==
null) ? (-1) : packages.IndexOf(target));
139 if (num < 0 || num2 < 0 || num == num2 || target.
builtin)
144 packages.Move(p, num2 - num);
166 ELayer.config.other.disableMods = on;
174 searchCache[package] = ModSearch.BuildText(package);
176 list.dragScrollView = GetComponentInChildren<UIScrollView>();
177 list.dragViewport =
windows[0].Rect();
188 list.dragEdgeSize =
list.
callbacks.GetMold()?.Rect().sizeDelta.y ?? 34f;
201 string title =
ELayer.
core.
mods.packages.IndexOf(a) + 1 +
". " + (a.isInPackages ?
"[Local] " :
"") + a.title.IsEmpty(a.dirInfo.Name);
203 b.buttonActivate.subText.text = a.version;
204 b.buttonLock.mainText.text = a.author;
221 bt.SetOnClick(delegate
223 a.willActivate = !a.willActivate;
228 bt.interactable = !a.builtin;
237 uIContextMenu.
AddButton(
"mod_publish", delegate
241 Dialog.
YesNo(
"mod_publish_warn".lang(a.title, a.id, a.author), delegate
243 ELayer.core.steam.CreateUserContent(a);
248 uIContextMenu.
AddButton(a.willActivate ?
"mod_deactivate" :
"mod_activate", delegate
251 a.willActivate = !a.willActivate;
252 ELayer.core.mods.SaveLoadOrder();
254 textRestart.SetActive(enable: true);
256 if (!a.isInPackages && !a.workshopId.IsEmpty())
258 uIContextMenu.
AddButton(
"mod_convert_local", delegate
261 string path = (
"Mod_" + a.workshopId +
"_" + a.id).SanitizeDirectoryName();
265 modPackage.UpdateMeta(updateOnly:
true);
266 searchCache[modPackage] = ModSearch.BuildText(modPackage);
268 modPackage.willActivate =
false;
269 modPackage.activated =
false;
275 if (a.isInPackages && a.IsSourceLocalizable)
277 uIContextMenu.
AddButton(
"mod_export_text", delegate
285 if (ModPreview.FindPreviewFile(a) !=
null || (bool)
SteamPreview(a))
287 uIContextMenu.
AddButton(
"mod_preview", delegate
292 if (!a.workshopId.IsEmpty())
294 uIContextMenu.
AddButton(
"mod_info_workshop", delegate
297 Application.OpenURL(
"https://steamcommunity.com/sharedfiles/filedetails/?id=" + a.workshopId.Trim());
300 uIContextMenu.
AddButton(
"mod_info", delegate
303 if (!a.dirInfo.Exists)
310 string text = a.dirInfo.FullName +
"/package.xml";
311 Util.ShowExplorer(File.Exists(text) ? text : a.dirInfo.FullName);
314 uIContextMenu.
Show();
322 if (package.
builtin == builtin && (builtin ||
Match(package)))
332 List<object> items = target.
items;
333 int num = items.IndexOf(p);
342 TextGenerationSettings generationSettings = text.GetGenerationSettings(Vector2.zero);
343 TextGenerator cachedTextGeneratorForLayout = text.cachedTextGeneratorForLayout;
344 float num = text.rectTransform.rect.width * text.pixelsPerUnit;
345 if (cachedTextGeneratorForLayout.GetPreferredWidth(
title, generationSettings) <= num)
349 int num2 =
title.Length;
350 while (num2 > 1 && cachedTextGeneratorForLayout.GetPreferredWidth(
title[..num2].TrimEnd() +
"..", generationSettings) > num)
354 return title[..num2].TrimEnd() +
"..";
373 text.text =
"mod_search".lang();
437 windows[0].rectBottom.RebuildLayout(recursive:
true);
445 ModSearch.Filter.Enabled =>
"mod_filter_enabled",
446 ModSearch.Filter.Disabled =>
"mod_filter_disabled",
447 ModSearch.Filter.Problems =>
"mod_filter_problem",
448 ModSearch.Filter.Local =>
"mod_filter_local",
449 ModSearch.Filter.Workshop =>
"mod_filter_workshop",
469 EventSystem current = EventSystem.current;
472 current.SetSelectedGameObject(
null);
480 if (
previews.TryGetValue(p, out var value))
489 Texture2D texture2D2 = ModPreview.Downscale(texture2D, 280, owns);
490 value.sprite = texture2D2.ToSprite();
491 value.ownsTexture = owns || texture2D2 != texture2D;
499 kind = ModPreview.PreviewType.None;
501 FileInfo fileInfo = ModPreview.FindPreviewFile(p);
502 if (fileInfo !=
null)
506 Texture2D texture2D = ModPreview.LoadTexture(File.ReadAllBytes(fileInfo.FullName), out kind, mipmap);
514 Debug.LogWarning(
"#mod preview " + fileInfo.FullName +
": " + ex.Message);
518 if ((
bool)texture2D2)
521 if (kind == ModPreview.PreviewType.None)
523 kind = ModPreview.PreviewType.Jpeg;
531 if (!(p.
item is WorkshopItem workshopItem) || !workshopItem.previewImage || workshopItem.previewImage.width <= 2)
535 return workshopItem.previewImage;
540 using (List<object>.Enumerator enumerator =
list.
items.GetEnumerator())
542 if (enumerator.MoveNext())
547 if (
manager.packages.Count <= 0)
564 infoPreview.image1.sprite = thumb.
sprite;
566 SetInfo(value: (thumb.
sprite ? ((thumb.
kind == ModPreview.PreviewType.Gif) ?
"mod_preview_gif" :
null) : ((thumb.
kind == ModPreview.PreviewType.None) ?
"mod_preview_none" :
"mod_preview_unsupported"))?.lang(),
item:
infoPreviewNote);
570 string text = ModLoadOrderPreset.WorkshopId(p);
571 SetTopic(
infoWorkshop, text.IsEmpty() ? p.
dirInfo.Name : text, text.IsEmpty() ?
"mod_filter_local" :
"mod_filter_workshop");
573 List<string>
list =
new List<string>();
581 list.
Add(array[0].lang(
string.Join(
"mod_info_or".lang(), array, 1, array.Length - 1)));
597 string[] tags = p.
tags;
598 SetTopic(
item, (tags !=
null && tags.Length > 0) ?
string.Join(
", ", p.
tags) :
null,
null);
606 panelScroll.content.anchoredPosition = Vector2.zero;
608 static string IdList(
string[][] rows,
bool alternatives)
614 string sep = (alternatives ?
"mod_info_or".lang() :
"\n");
615 return string.Join(
"\n", from row in rows
616 where row !=
null && row.Length > 0
617 select
string.Join(sep, row.Where((
string id) => !
id.IsEmpty())) into line
618 where !line.IsEmpty()
621 static void SetInfo(
UIItem uIItem,
string value)
623 uIItem.SetActive(!value.IsEmpty());
624 if (!value.IsEmpty())
629 static void SetTopic(
UIItem uIItem,
string value,
string lang)
631 uIItem.SetActive(!value.IsEmpty());
632 if (!value.IsEmpty())
646 ModPreview.PreviewType kind;
652 ELayer.
ui.Say(
"mod_preview_unsupported");
655 Sprite image = tex.ToSprite();
660 UnityEngine.Object.Destroy(tex);
663 UnityEngine.Object.Destroy(tex);
678 uIContextMenu.
AddButton(
"mod_preset_load", delegate
682 uIContextMenu.
AddButton(
"mod_preset_delete", delegate
688 uIContextMenu.
AddButton(
"mod_preset_folder", delegate
693 uIContextMenu.
Show();
698 Dialog.
InputName(
"mod_preset_name",
"mod_preset_default_name".lang(), delegate(
bool cancel,
string text)
702 string name = (text ??
"").Trim().SanitizeFileName().Trim();
709 Dialog.
YesNo(
"mod_preset_overwrite".lang(name), delegate
730 ELayer.
ui.Say(
"mod_preset_saved".lang(name));
736 if (files.Count == 0)
741 Dialog.List(
"mod_preset_select", files, (FileInfo f) => Path.GetFileNameWithoutExtension(f.Name), delegate(
int i,
string _)
762 string name = Path.GetFileNameWithoutExtension(file.Name);
763 Dialog.
YesNo(
"mod_preset_delete_confirm".lang(name), delegate
770 ELayer.
ui.Say(
"mod_preset_deleted".lang(name));
777 if (preset.entries.Count == 0)
782 GUIUtility.systemCopyBuffer = ModLoadOrderPreset.Serialize(preset);
789 if (!ModLoadOrderPreset.TryParse(GUIUtility.systemCopyBuffer, out var preset, out var _))
794 if (preset.name.IsEmpty())
796 preset.name =
"mod_preset_default_name".lang();
803 List<ModLoadOrderPreset.Entry>
list = ModLoadOrderPreset.FindMissing(
manager.packages, preset);
812 },
null,
"mod_preset_apply",
"cancel");
815 private static string DescribeEntries(List<ModLoadOrderPreset.Entry> entries,
int max)
817 StringBuilder stringBuilder =
new StringBuilder();
818 for (
int i = 0; i < entries.Count && i < max; i++)
820 ModLoadOrderPreset.Entry entry = entries[i];
821 stringBuilder.Append(entry.title.IsEmpty() ? entry.id : (entry.title +
" (" + entry.id +
")")).Append(
'\n');
823 if (entries.Count > max)
825 stringBuilder.Append(
"mod_preset_more".lang((entries.Count - max).ToString() ??
"")).Append(
'\n');
827 return stringBuilder.ToString().TrimEnd();
841 if (!preset.gameVersion.IsEmpty() && preset.gameVersion != text)
843 ELayer.
ui.Say(
"mod_preset_version_warn".lang(preset.gameVersion, text));
845 ELayer.
ui.Say(
"mod_preset_applied".lang(preset.name, applyResult.enabled.ToString() ??
"", applyResult.missing.Count.ToString() ??
""));
864 UnityEngine.Object.Destroy(value.
sprite.texture);
866 UnityEngine.Object.Destroy(value.
sprite);
virtual void FreezeScreen(float duration=0.2f)
UIList.ICallback callbacks
BaseModPackage duplicateOf
void UpdateMeta(bool updateOnly=false)
static string PathLoadOrderPreset
static void TryWarnUpload(Action action)
static Dialog YesNo(string langDetail, Action actionYes, Action actionNo=null, string langYes="yes", string langNo="no")
static Dialog InputName(string langDetail, string text, Action< bool, string > onClose, InputType inputType=InputType.Default)
static Dialog Ok(string langDetail, Action action=null)
void SetImage(Sprite sprite)
void OnPointerEnter(PointerEventData eventData)
ModPreview.PreviewType kind
const string urlWorkshopItem
UIList.Callback< ModPackage, ItemMod > CreateCallbacks(UIList target, bool builtin)
void ShowInfo(BaseModPackage p)
void SelectPreset(Action< FileInfo > onSelect)
bool Match(BaseModPackage p)
UIButton buttonClearSearch
static Texture2D LoadPreviewTexture(BaseModPackage p, bool mipmap, out ModPreview.PreviewType kind, out bool owns)
void Move(BaseModPackage p, int a)
void RefreshFilterButton()
ModSearch.Filter filterMode
UIButton toggleDisableMods
void ApplyPreset(ModLoadOrderPreset.Preset preset)
PreviewEntry GetThumb(BaseModPackage p)
BaseModPackage panelTarget
void ShowPreview(BaseModPackage a)
static string FilterLabel(ModSearch.Filter f)
static Texture2D SteamPreview(BaseModPackage p)
void ApplyPresetFile(FileInfo file)
void MoveTo(BaseModPackage p, BaseModPackage target)
readonly Dictionary< BaseModPackage, string > searchCache
void WritePreset(string name)
static string DescribeEntries(List< ModLoadOrderPreset.Entry > entries, int max)
readonly Dictionary< BaseModPackage, PreviewEntry > previews
void DeletePreset(FileInfo file)
void ConfirmPreset(ModLoadOrderPreset.Preset preset)
BaseModPackage FirstInfoTarget()
static string FitTitle(UIText text, string title)
Layer SetOnKill(Action action)
bool TryLoadPresetFile(FileInfo file, out ModLoadOrderPreset.Preset preset, out string error)
ModLoadOrderPreset.ApplyResult ApplyPreset(ModLoadOrderPreset.Preset preset, bool disableOthers=true)
static string GetPresetPath(string name)
ModPackage AddPackage(DirectoryInfo dir, bool isInPackages=false)
bool SavePreset(string name, out string path)
List< FileInfo > ListPresets()
void CopyContentTo(string dir)
override string UpdateSourceLocalizationFile(string lang, bool force=false)
override void Add(object item)