Elin Decompiled Documentation EA 23.356.1 Nightly
Loading...
Searching...
No Matches
LayerMod.cs
Go to the documentation of this file.
1using System;
2using System.Collections.Generic;
3using System.IO;
4using System.Linq;
5using System.Text;
6using HeathenEngineering.SteamworksIntegration;
7using UnityEngine;
8using UnityEngine.EventSystems;
9using UnityEngine.UI;
10
11public class LayerMod : ELayer
12{
13 private sealed class PreviewEntry
14 {
15 public Sprite sprite;
16
17 public bool ownsTexture;
18
19 public ModPreview.PreviewType kind;
20 }
21
22 private sealed class HoverRelay : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler
23 {
24 public Action onEnter;
25
26 public void OnPointerEnter(PointerEventData eventData)
27 {
28 onEnter?.Invoke();
29 }
30 }
31
32 private const string urlWorkshopItem = "https://steamcommunity.com/sharedfiles/filedetails/?id=";
33
34 public static LayerMod Instance;
35
36 public UIList list;
37
38 public UIList list2;
39
41
43
45
47
48 public InputField inputSearch;
49
51
53
55
57
59
61
63
65
66 public UIItem infoId;
67
69
71
73
75
77
79
81
83
85
86 public GameObject infoSpace;
87
88 public Sprite spriteNoPreview;
89
91
93
95
96 private float timerSearch;
97
98 private bool wasSearchFocused;
99
100 private string lastSearch = "";
101
102 private string[] searchTerms = Array.Empty<string>();
103
104 private ModSearch.Filter filterMode;
105
106 private readonly Dictionary<BaseModPackage, string> searchCache = new Dictionary<BaseModPackage, string>();
107
108 private readonly Dictionary<BaseModPackage, PreviewEntry> previews = new Dictionary<BaseModPackage, PreviewEntry>();
109
111
112 public bool HasFilter
113 {
114 get
115 {
116 if (searchTerms.Length == 0)
117 {
118 return filterMode != ModSearch.Filter.All;
119 }
120 return true;
121 }
122 }
123
124 private void Move(object row, int a)
125 {
126 List<object> items = list.items;
127 int num = items.IndexOf(row);
128 if (a > 0 && row is ModGroup { collapsed: false } modGroup)
129 {
130 a += Members(modGroup).Count;
131 }
132 if (num < 0 || num + a < 0 || num + a >= items.Count)
133 {
134 SE.BeepSmall();
135 return;
136 }
137 object obj = items[num + a];
138 ModGroup modGroup2;
139 bool num2;
140 if (!HasFilter && row is BaseModPackage baseModPackage)
141 {
142 modGroup2 = (obj as BaseModPackage)?.group;
143 if (a <= 0)
144 {
145 if (baseModPackage.group == null)
146 {
147 num2 = modGroup2 != null;
148 goto IL_00b8;
149 }
150 }
151 else if (baseModPackage.group != null)
152 {
153 num2 = modGroup2 != baseModPackage.group;
154 goto IL_00b8;
155 }
156 }
157 goto IL_00de;
158 IL_00b8:
159 if (num2)
160 {
161 if (a > 0)
162 {
163 LeaveGroup(baseModPackage);
164 }
165 baseModPackage.group = ((a > 0) ? null : modGroup2);
166 OnReorder();
167 return;
168 }
169 goto IL_00de;
170 IL_00de:
171 MoveTo(row, obj);
172 }
173
174 private void MoveTo(object row, object target)
175 {
176 List<BaseModPackage> packages = manager.packages;
177 List<ModGroup> emptyGroups = manager.emptyGroups;
178 List<object> items = this.list.items;
179 ModGroup modGroup = row as ModGroup;
180 BaseModPackage baseModPackage = target as BaseModPackage;
181 ModGroup modGroup2 = (target as ModGroup) ?? ((modGroup == null) ? null : baseModPackage?.group);
182 if (target == null || target == row || (baseModPackage != null && baseModPackage.builtin) || (modGroup != null && modGroup == modGroup2))
183 {
184 SE.BeepSmall();
185 RefreshLists();
186 return;
187 }
188 bool flag = items.IndexOf(row) < items.IndexOf(target);
189 List<BaseModPackage> block = ((modGroup != null) ? Members(modGroup) : new List<BaseModPackage> { (BaseModPackage)row });
190 bool flag2 = emptyGroups.Contains(modGroup2);
191 if (block.Count == 0)
192 {
193 (BaseModPackage, int) tuple = (modGroup.after, emptyGroups.IndexOf(modGroup));
194 emptyGroups.Remove(modGroup);
195 if (flag2)
196 {
197 modGroup.after = modGroup2.after;
198 emptyGroups.Insert(emptyGroups.IndexOf(modGroup2) + (flag ? 1 : 0), modGroup);
199 }
200 else
201 {
202 List<BaseModPackage> list = ((modGroup2 != null) ? Members(modGroup2) : null);
203 BaseModPackage edge = ((list == null || list.Count <= 0) ? baseModPackage : (flag ? list[^1] : list[0]));
204 modGroup.after = (flag ? edge : packages.TakeWhile((BaseModPackage p) => p != edge).LastOrDefault((BaseModPackage p) => !p.builtin));
205 emptyGroups.Insert(GetGroupIndex(modGroup.after, !flag), modGroup);
206 }
207 BaseModPackage after = modGroup.after;
208 int num = emptyGroups.IndexOf(modGroup);
209 var (baseModPackage2, num2) = tuple;
210 if (after == baseModPackage2 && num == num2)
211 {
212 SE.BeepSmall();
213 RefreshLists();
214 }
215 else
216 {
217 OnReorder(restart: false);
218 }
219 return;
220 }
221 bool flag3 = modGroup == null && flag && (flag2 || (modGroup2 != null && !modGroup2.collapsed));
222 ModGroup modGroup3 = ((modGroup != null) ? block[0].group : ((modGroup2 == null) ? baseModPackage.group : (flag3 ? modGroup2 : null)));
223 if (modGroup == null && modGroup3 != block[0].group)
224 {
225 LeaveGroup(block[0]);
226 }
227 int num3 = packages.IndexOf(block[0]);
228 BaseModPackage after2 = packages.TakeWhile((BaseModPackage p) => p != block[0]).LastOrDefault((BaseModPackage p) => !p.builtin);
229 foreach (BaseModPackage item in block)
230 {
231 packages.Remove(item);
232 }
233 List<BaseModPackage> list2 = ((modGroup2 != null) ? Members(modGroup2) : null);
234 bool flag4 = flag && !flag3;
235 BaseModPackage baseModPackage3 = ((list2 == null) ? baseModPackage : ((list2.Count == 0) ? null : (flag4 ? list2[^1] : list2[0])));
236 int num4 = ((baseModPackage3 != null) ? (packages.IndexOf(baseModPackage3) + (flag4 ? 1 : 0)) : ((flag2 && !block.Contains(modGroup2.after)) ? ((modGroup2.after != null) ? (packages.IndexOf(modGroup2.after) + 1) : packages.Count((BaseModPackage p) => p.builtin)) : num3));
237 if (!flag2 && num4 == num3 && modGroup3 == block[0].group)
238 {
239 SE.BeepSmall();
240 RefreshLists();
241 return;
242 }
243 packages.InsertRange(num4, block);
244 BaseModPackage baseModPackage4 = (flag2 ? modGroup2.after : null);
245 foreach (ModGroup item2 in emptyGroups)
246 {
247 if (block.Contains(item2.after) && (num4 != num3 || (flag2 && flag && emptyGroups.IndexOf(item2) <= emptyGroups.IndexOf(modGroup2))))
248 {
249 item2.after = after2;
250 }
251 else if ((baseModPackage3 != null && flag4 && item2.after == baseModPackage3) || (flag2 && !flag && item2.after == baseModPackage4 && emptyGroups.IndexOf(item2) >= emptyGroups.IndexOf(modGroup2)))
252 {
253 item2.after = block[^1];
254 }
255 }
256 block[0].group = modGroup3;
257 OnReorder();
258 }
259
260 private void OnReorder(bool restart = true)
261 {
262 SE.Tab();
263 if (restart)
264 {
265 textRestart.SetActive(enable: true);
266 }
267 manager.emptyGroups.RemoveAll((ModGroup g) => manager.packages.Any((BaseModPackage p) => p.group == g));
269 RefreshLists();
270 }
271
272 public void RefreshLists()
273 {
274 list.List();
275 list2.List();
276 if ((bool)textNoResult)
277 {
278 textNoResult.SetActive(HasFilter && list.items.Count == 0);
279 }
280 if ((bool)buttonCollapse)
281 {
282 buttonCollapse.mainText.text = (Groups().Any((ModGroup g) => !g.collapsed) ? "mod_group_collapse_all" : "mod_group_expand_all").lang();
283 windows[0].rectBottom.RebuildLayout(recursive: true);
284 }
285 }
286
287 public override void OnInit()
288 {
289 textRestart.SetActive(enable: false);
291 {
292 ELayer.config.other.disableMods = on;
294 textRestart.SetActive(enable: true);
295 });
296 Instance = this;
297 foreach (BaseModPackage package in manager.packages)
298 {
299 package.UpdateMeta(updateOnly: true);
300 searchCache[package] = ModSearch.BuildText(package);
301 }
302 list.dragScrollView = list.GetComponentInParent<UIScrollView>();
303 list.dragViewport = windows[0].Rect();
304 list.onDragBegin = delegate(object row)
305 {
306 if (row is ModGroup g)
307 {
308 SetMembersActive(g, active: false);
309 }
310 };
311 list.callbacks = CreateCallbacks(list, builtin: false);
312 list2.callbacks = CreateCallbacks(list2, builtin: true);
313 InitSearchUI();
314 windows[0].AddBottomButton("mod_preset", ShowPresetMenu);
315 windows[0].AddBottomButton("mod_group_new", NewGroup);
316 buttonCollapse = windows[0].AddBottomButton("mod_group_collapse_all", CollapseAll);
317 infoPreview.button1.SetOnClick(delegate
318 {
320 });
321 RefreshLists();
323 list.dragEdgeSize = list.callbacks.GetMold()?.Rect().sizeDelta.y ?? 34f;
324 }
325
326 private UIList.Callback<object, ItemMod> CreateCallbacks(UIList target, bool builtin)
327 {
328 return new UIList.Callback<object, ItemMod>
329 {
330 onClick = delegate
331 {
332 },
333 onInstantiate = delegate(object row, ItemMod b)
334 {
335 if (row is ModGroup g)
336 {
337 SetGroupRow(g, b);
338 }
339 else
340 {
341 SetModRow((ModPackage)row, b);
342 }
343 },
344 onList = delegate
345 {
346 ModGroup modGroup = null;
347 if (!builtin && !HasFilter)
348 {
349 foreach (ModGroup emptyGroup in manager.emptyGroups)
350 {
351 if (emptyGroup.after == null)
352 {
353 target.Add(emptyGroup);
354 }
355 }
356 }
357 foreach (BaseModPackage package in manager.packages)
358 {
359 if (package.builtin == builtin && (builtin || Match(package)))
360 {
361 if (!HasFilter && package.group != modGroup)
362 {
363 modGroup = package.group;
364 if (modGroup != null)
365 {
366 target.Add(modGroup);
367 }
368 }
369 if (HasFilter || modGroup == null || !modGroup.collapsed)
370 {
371 target.Add(package);
372 }
373 if (!HasFilter)
374 {
375 foreach (ModGroup emptyGroup2 in manager.emptyGroups)
376 {
377 if (emptyGroup2.after == package)
378 {
379 target.Add(emptyGroup2);
380 }
381 }
382 }
383 }
384 }
385 },
386 onRefresh = Refresh,
387 onDragReorder = delegate(object row, int a)
388 {
389 if (row is ModGroup g)
390 {
391 SetMembersActive(g, active: true);
392 }
393 if (a != 0)
394 {
395 List<object> items = target.items;
396 int num = items.IndexOf(row);
397 MoveTo(row, items[Mathf.Clamp(num + a, 0, items.Count - 1)]);
398 }
399 },
400 canDragReorder = (object row) => !(row is BaseModPackage baseModPackage) || !baseModPackage.builtin
401 };
402 }
403
404 private void SetModRow(ModPackage a, ItemMod b)
405 {
406 b.package = a;
407 string title = ((a.group != null && !HasFilter) ? " " : "") + (ELayer.core.mods.packages.IndexOf(a) + 1) + ". " + (a.isInPackages ? "[Local] " : "") + a.title.IsEmpty(a.dirInfo.Name);
408 b.buttonActivate.mainText.SetText(FitTitle(b.buttonActivate.mainText, title), (!a.IsValidVersion() || a.blockedBy != null || !a.langDepError.IsEmpty()) ? FontColor.Bad : (a.activated ? FontColor.ButtonGeneral : FontColor.Passive));
409 b.buttonActivate.subText.text = a.version;
410 b.buttonLock.mainText.text = a.author;
411 ItemMod itemMod = ((a.group != null && !HasFilter) ? list.GetPair<ItemMod>(a.group) : null);
412 b.imageMember.SetActive(itemMod);
413 if ((bool)itemMod)
414 {
415 b.imageMember.color = itemMod.buttonActivate.mainText.color;
416 }
417 b.buttonUp.SetActive(!a.builtin);
418 b.buttonDown.SetActive(!a.builtin);
419 b.buttonConfig.SetActive(a.onBuildConfig != null);
420 b.buttonConfig.SetOnClick(delegate
421 {
423 });
424 b.buttonToggle.SetToggle(a.willActivate);
425 b.buttonUp.SetOnClick(delegate
426 {
427 Move(a, -1);
428 });
429 b.buttonDown.SetOnClick(delegate
430 {
431 Move(a, 1);
432 });
433 b.buttonActivate.GetOrCreate<HoverRelay>().onEnter = delegate
434 {
435 ShowInfo(a);
436 };
437 UIButton bt = b.buttonToggle;
438 bt.SetOnClick(delegate
439 {
440 a.willActivate = !a.willActivate;
441 bt.SetCheck(a.willActivate);
443 textRestart.SetActive(enable: true);
444 if (a.group != null && !HasFilter)
445 {
446 SetGroupRow(a.group, list.GetPair<ItemMod>(a.group));
447 }
448 });
449 bt.interactable = !a.builtin;
450 b.buttonActivate.onClick.AddListener(delegate
451 {
452 Refresh();
453 UIContextMenu uIContextMenu = ELayer.ui.CreateContextMenuInteraction().SetHighlightTarget(b.buttonActivate);
454 if (!a.builtin)
455 {
456 if (ELayer.debug.enable || (!BaseCore.IsOffline && a.isInPackages && !ELayer.core.version.demo))
457 {
458 uIContextMenu.AddButton("mod_publish", delegate
459 {
460 Core.TryWarnUpload(delegate
461 {
462 Dialog.YesNo("mod_publish_warn".lang(a.title, a.id, a.author), delegate
463 {
464 ELayer.core.steam.CreateUserContent(a);
465 });
466 });
467 });
468 }
469 uIContextMenu.AddButton(a.willActivate ? "mod_deactivate" : "mod_activate", delegate
470 {
471 SE.Click();
472 a.willActivate = !a.willActivate;
473 ELayer.core.mods.SaveLoadOrder();
474 RefreshLists();
475 textRestart.SetActive(enable: true);
476 });
477 if (!a.isInPackages && !a.workshopId.IsEmpty())
478 {
479 uIContextMenu.AddButton("mod_convert_local", delegate
480 {
481 SE.Click();
482 string path = ("Mod_" + a.workshopId + "_" + a.id).SanitizeDirectoryName();
483 string text = Path.Combine(BaseModManager.rootMod, path);
484 a.CopyContentTo(text);
485 ModPackage modPackage = manager.AddPackage(new DirectoryInfo(text), isInPackages: true);
486 modPackage.UpdateMeta(updateOnly: true);
487 searchCache[modPackage] = ModSearch.BuildText(modPackage);
488 manager.packages.Move(modPackage, manager.packages.IndexOf(a) - manager.packages.Count + 2);
489 modPackage.group = a.group;
490 modPackage.willActivate = false;
491 modPackage.activated = false;
493 RefreshLists();
494 textRestart.SetActive(enable: true);
495 });
496 }
497 if (a.isInPackages && a.IsSourceLocalizable)
498 {
499 uIContextMenu.AddButton("mod_export_text", delegate
500 {
501 SE.Click();
502 string text = a.UpdateSourceLocalizationFile(Lang.langCode, force: true);
503 ELayer.ui.Say(text);
504 });
505 }
506 AddGroupButtons(uIContextMenu, a);
507 }
508 if (a.onBuildConfig != null)
509 {
510 uIContextMenu.AddButton("config", delegate
511 {
512 SE.Click();
514 });
515 }
516 if (ModPreview.FindPreviewFile(a) != null || (bool)SteamPreview(a))
517 {
518 uIContextMenu.AddButton("mod_preview", delegate
519 {
520 ShowPreview(a);
521 });
522 }
523 if (!a.workshopId.IsEmpty())
524 {
525 uIContextMenu.AddButton("mod_info_workshop", delegate
526 {
527 SE.Click();
528 Application.OpenURL("https://steamcommunity.com/sharedfiles/filedetails/?id=" + a.workshopId.Trim());
529 });
530 }
531 if (!a.id.IsEmpty())
532 {
533 uIContextMenu.AddButton("mod_id_copy", delegate
534 {
535 SE.Click();
536 GUIUtility.systemCopyBuffer = a.id;
537 ELayer.ui.Say("mod_id_copied".lang(a.id));
538 });
539 }
540 uIContextMenu.AddButton("mod_info", delegate
541 {
542 SE.Click();
543 if (!a.dirInfo.Exists)
544 {
545 SE.BeepSmall();
546 ELayer.ui.Say(a.dirInfo.FullName);
547 }
548 else
549 {
550 string text = a.dirInfo.FullName + "/package.xml";
551 Util.ShowExplorer(File.Exists(text) ? text : a.dirInfo.FullName);
552 }
553 });
554 uIContextMenu.Show();
555 });
556 b.buttonLock.onClick.AddListener(Refresh);
557 }
558
559 private List<BaseModPackage> Members(ModGroup g)
560 {
561 return manager.packages.Where((BaseModPackage p) => p.group == g).ToList();
562 }
563
564 private IEnumerable<ModGroup> Groups()
565 {
566 return (from p in manager.packages
567 select p.@group into g
568 where g != null
569 select g).Distinct().Concat(manager.emptyGroups);
570 }
571
572 private void SetMembersActive(ModGroup g, bool active)
573 {
574 if (g.collapsed)
575 {
576 return;
577 }
578 foreach (BaseModPackage item in Members(g))
579 {
580 list.GetPair(item).component.SetActive(active);
581 }
582 }
583
585 {
586 ModGroup g = p.group;
587 if (g != null && !manager.packages.Any((BaseModPackage m) => m != p && m.group == g))
588 {
589 manager.emptyGroups.Insert(GetGroupIndex(p, last: false), g);
590 g.after = manager.packages.TakeWhile((BaseModPackage m) => m != p).LastOrDefault((BaseModPackage m) => !m.builtin);
591 }
592 }
593
594 private int GetGroupIndex(BaseModPackage anchor, bool last)
595 {
596 List<BaseModPackage> l = manager.packages;
597 return manager.emptyGroups.Count((ModGroup e) => l.IndexOf(e.after) < l.IndexOf(anchor) || (last && e.after == anchor));
598 }
599
600 private void NewGroup()
601 {
603 {
604 SE.BeepSmall();
605 return;
606 }
607 SE.Click();
608 InputGroupName("mod_group_default_name".lang(), delegate(string name)
609 {
610 if (HasFilter)
611 {
612 ClearSearch();
613 }
615 {
616 name = name,
617 after = manager.packages.LastOrDefault((BaseModPackage p) => !p.builtin)
618 };
620 OnReorder(restart: false);
621 list.dragScrollView.content.RebuildLayout(recursive: true);
622 list.dragScrollView.verticalNormalizedPosition = 0f;
623 });
624 }
625
626 private void SetGroupRow(ModGroup g, ItemMod b)
627 {
628 List<BaseModPackage> members = Members(g);
629 int on = members.Count((BaseModPackage p) => p.willActivate);
630 string title = ((members.Count == 0) ? "" : (g.collapsed ? "[+] " : "[-] ")) + g.name;
631 UIText mainText = b.buttonActivate.mainText;
632 mainText.fontStyle = FontStyle.Bold;
633 mainText.SetText(FitTitle(mainText, title, (members.Count > 0) ? (" (" + on + "/" + members.Count + ")") : ""), FontColor.Topic);
634 Color topic = mainText.color;
635 Color? color = g.color;
636 if (color.HasValue)
637 {
638 Color valueOrDefault = color.GetValueOrDefault();
639 mainText.SetText(mainText.text, valueOrDefault.Multiply(0.45f, 0f));
640 }
641 b.imageGroup.SetActive(enable: true);
642 b.imageGroup.color = (g.color ?? topic).SetAlpha(0.4f);
643 b.buttonActivate.subText.text = "";
644 b.buttonLock.mainText.text = "";
645 b.buttonUp.SetOnClick(delegate
646 {
647 Move(g, -1);
648 });
649 b.buttonDown.SetOnClick(delegate
650 {
651 Move(g, 1);
652 });
653 b.buttonToggle.SetToggle(on > 0 && on == members.Count);
654 b.buttonToggle.interactable = members.Count > 0;
655 b.buttonToggle.SetOnClick(delegate
656 {
657 foreach (BaseModPackage item in members)
658 {
659 item.willActivate = on != members.Count;
660 }
661 OnReorder();
662 });
663 b.buttonActivate.SetOnClick(delegate
664 {
665 g.collapsed = !g.collapsed;
666 OnReorder(restart: false);
667 });
668 b.buttonRename.SetActive(enable: true);
669 b.buttonRename.SetOnClick(delegate
670 {
671 InputGroupName(g.name, delegate(string name)
672 {
673 g.name = name;
674 OnReorder(restart: false);
675 });
676 });
677 b.buttonColor.SetActive(enable: true);
678 b.buttonColor.SetOnClick(delegate
679 {
680 ELayer.ui.AddLayer<LayerColorPicker>().SetColor(g.color ?? topic, topic, delegate(PickerState state, Color c)
681 {
682 c.a = topic.a;
683 g.color = ((c == topic) ? ((Color?)null) : new Color?(c));
684 if (state == PickerState.Confirm)
685 {
686 OnReorder(restart: false);
687 }
688 else
689 {
690 SetGroupRow(g, b);
691 }
692 });
693 });
694 b.buttonDisband.SetActive(enable: true);
695 b.buttonDisband.SetOnClick(delegate
696 {
697 foreach (BaseModPackage item2 in members)
698 {
699 item2.group = null;
700 }
701 manager.emptyGroups.Remove(g);
702 OnReorder(restart: false);
703 });
704 }
705
707 {
708 m.AddButton("mod_group_new", delegate
709 {
710 InputGroupName("mod_group_default_name".lang(), delegate(string name)
711 {
712 SetGroup(a, new ModGroup
713 {
714 name = name
715 });
716 });
717 });
718 List<ModGroup> groups = (from g in Groups()
719 where g != a.@group
720 select g).ToList();
721 if (groups.Count > 0)
722 {
723 m.AddButton("mod_group_move", delegate
724 {
725 SE.Click();
726 Dialog.List("mod_group_select", groups, (ModGroup g) => g.name, delegate(int i, string _)
727 {
728 SetGroup(a, groups[i]);
729 return true;
730 }, canCancel: true);
731 });
732 }
733 if (a.group != null)
734 {
735 m.AddButton("mod_group_remove", delegate
736 {
737 SetGroup(a, null);
738 });
739 }
740 }
741
743 {
744 if (HasFilter)
745 {
746 ClearSearch();
747 }
748 List<BaseModPackage> packages = manager.packages;
749 List<ModGroup> emptyGroups = manager.emptyGroups;
750 ModGroup host = ((g != null && packages.Any((BaseModPackage m) => m.group == g)) ? g : p.group);
751 BaseModPackage baseModPackage = ((host == null) ? null : packages.LastOrDefault((BaseModPackage m) => m != p && m.group == host));
752 if (g != p.group)
753 {
754 LeaveGroup(p);
755 }
756 int num = packages.IndexOf(p);
757 BaseModPackage after = packages.TakeWhile((BaseModPackage m) => m != p).LastOrDefault((BaseModPackage m) => !m.builtin);
758 packages.Remove(p);
759 int num2 = ((!emptyGroups.Contains(g)) ? ((baseModPackage != null) ? (packages.IndexOf(baseModPackage) + 1) : num) : ((g.after == p) ? num : ((g.after != null) ? (packages.IndexOf(g.after) + 1) : packages.Count((BaseModPackage m) => m.builtin))));
760 packages.Insert(num2, p);
761 BaseModPackage baseModPackage2 = (emptyGroups.Contains(g) ? g.after : null);
762 foreach (ModGroup item in emptyGroups)
763 {
764 if (item.after == p && num2 != num)
765 {
766 item.after = after;
767 }
768 else if (emptyGroups.Contains(g) && item.after == baseModPackage2 && emptyGroups.IndexOf(item) >= emptyGroups.IndexOf(g))
769 {
770 item.after = p;
771 }
772 }
773 p.group = g;
774 if (g != null)
775 {
776 g.collapsed = false;
777 }
778 OnReorder();
779 }
780
781 private void CollapseAll()
782 {
783 List<ModGroup> list = Groups().ToList();
784 if (list.Count == 0)
785 {
786 SE.BeepSmall();
787 return;
788 }
789 bool collapsed = list.Any((ModGroup g) => !g.collapsed);
790 foreach (ModGroup item in list)
791 {
792 item.collapsed = collapsed;
793 }
794 OnReorder(restart: false);
795 }
796
797 private void InputGroupName(string text, Action<string> onInput)
798 {
799 Dialog.InputName("mod_group_name", text, delegate(bool cancel, string s)
800 {
801 if (!cancel)
802 {
803 string text2 = (s ?? "").Trim();
804 if (text2.IsEmpty())
805 {
806 SE.BeepSmall();
807 }
808 else
809 {
810 onInput(text2);
811 }
812 }
813 });
814 }
815
816 private static string FitTitle(UIText text, string title, string suffix = "")
817 {
818 TextGenerationSettings generationSettings = text.GetGenerationSettings(Vector2.zero);
819 TextGenerator cachedTextGeneratorForLayout = text.cachedTextGeneratorForLayout;
820 float num = text.rectTransform.rect.width * text.pixelsPerUnit;
821 if (cachedTextGeneratorForLayout.GetPreferredWidth(title + suffix, generationSettings) <= num)
822 {
823 return title + suffix;
824 }
825 int num2 = title.Length;
826 while (num2 > 1 && cachedTextGeneratorForLayout.GetPreferredWidth(title[..num2].TrimEnd() + ".." + suffix, generationSettings) > num)
827 {
828 num2--;
829 }
830 return title[..num2].TrimEnd() + ".." + suffix;
831 }
832
833 private bool Match(BaseModPackage p)
834 {
835 if (!searchCache.TryGetValue(p, out var value))
836 {
837 value = (searchCache[p] = ModSearch.BuildText(p));
838 }
839 return ModSearch.Match(p, value, searchTerms, filterMode);
840 }
841
842 private void InitSearchUI()
843 {
844 if ((bool)inputSearch)
845 {
846 inputSearch.SetTextWithoutNotify("");
847 if (inputSearch.placeholder is Text text)
848 {
849 text.text = "mod_search".lang();
850 }
851 inputSearch.onValueChanged.AddListener(Search);
852 inputSearch.onSubmit.AddListener(Search);
853 }
854 if ((bool)buttonClearSearch)
855 {
857 }
858 buttonFilter = windows[0].AddBottomButton("mod_filter", CycleFilter);
860 }
861
862 public void Search(string s)
863 {
864 lastSearch = s ?? "";
865 timerSearch = 0.15f;
866 if ((bool)buttonClearSearch)
867 {
868 buttonClearSearch.SetActive(!lastSearch.IsEmpty());
869 }
870 }
871
872 private void ClearSearchText()
873 {
874 SE.Click();
875 if ((bool)inputSearch)
876 {
877 inputSearch.SetTextWithoutNotify("");
878 }
879 Search("");
880 }
881
882 public void ClearSearch()
883 {
884 if ((bool)inputSearch)
885 {
886 inputSearch.SetTextWithoutNotify("");
887 }
888 if ((bool)buttonClearSearch)
889 {
890 buttonClearSearch.SetActive(enable: false);
891 }
892 lastSearch = "";
893 timerSearch = 0f;
894 searchTerms = Array.Empty<string>();
895 filterMode = ModSearch.Filter.All;
897 RefreshLists();
898 }
899
900 private void CycleFilter()
901 {
902 SE.Click();
903 filterMode = ModSearch.Filters[(int)(filterMode + 1) % ModSearch.Filters.Length];
905 RefreshLists();
906 }
907
908 private void RefreshFilterButton()
909 {
910 if ((bool)buttonFilter)
911 {
912 buttonFilter.mainText.text = "mod_filter".lang() + ": " + FilterLabel(filterMode).lang();
913 windows[0].rectBottom.RebuildLayout(recursive: true);
914 }
915 }
916
917 private static string FilterLabel(ModSearch.Filter f)
918 {
919 return f switch
920 {
921 ModSearch.Filter.Enabled => "mod_filter_enabled",
922 ModSearch.Filter.Disabled => "mod_filter_disabled",
923 ModSearch.Filter.Problems => "mod_filter_problem",
924 ModSearch.Filter.Local => "mod_filter_local",
925 ModSearch.Filter.Workshop => "mod_filter_workshop",
926 _ => "all",
927 };
928 }
929
930 private void LateUpdate()
931 {
932 if (timerSearch > 0f)
933 {
935 if (timerSearch <= 0f)
936 {
937 timerSearch = 0f;
938 searchTerms = ModSearch.Terms(lastSearch);
939 RefreshLists();
940 }
941 }
942 if ((bool)inputSearch)
943 {
944 bool isFocused = inputSearch.isFocused;
945 EventSystem current = EventSystem.current;
946 if (wasSearchFocused && !isFocused && (bool)current && current.currentSelectedGameObject == inputSearch.gameObject)
947 {
948 current.SetSelectedGameObject(null);
949 }
950 wasSearchFocused = isFocused;
951 }
952 }
953
955 {
956 if (previews.TryGetValue(p, out var value))
957 {
958 return value;
959 }
960 value = new PreviewEntry();
961 bool owns;
962 Texture2D texture2D = LoadPreviewTexture(p, mipmap: true, out value.kind, out owns);
963 if ((bool)texture2D)
964 {
965 Texture2D texture2D2 = ModPreview.Downscale(texture2D, 280, owns);
966 value.sprite = texture2D2.ToSprite();
967 value.ownsTexture = owns || texture2D2 != texture2D;
968 }
969 previews[p] = value;
970 return value;
971 }
972
973 private static Texture2D LoadPreviewTexture(BaseModPackage p, bool mipmap, out ModPreview.PreviewType kind, out bool owns)
974 {
975 kind = ModPreview.PreviewType.None;
976 owns = true;
977 FileInfo fileInfo = ModPreview.FindPreviewFile(p);
978 if (fileInfo != null)
979 {
980 try
981 {
982 Texture2D texture2D = ModPreview.LoadTexture(File.ReadAllBytes(fileInfo.FullName), out kind, mipmap);
983 if ((bool)texture2D)
984 {
985 return texture2D;
986 }
987 }
988 catch (Exception ex)
989 {
990 Debug.LogWarning("#mod preview " + fileInfo.FullName + ": " + ex.Message);
991 }
992 }
993 Texture2D texture2D2 = SteamPreview(p);
994 if ((bool)texture2D2)
995 {
996 owns = false;
997 if (kind == ModPreview.PreviewType.None)
998 {
999 kind = ModPreview.PreviewType.Jpeg;
1000 }
1001 }
1002 return texture2D2;
1003 }
1004
1005 private static Texture2D SteamPreview(BaseModPackage p)
1006 {
1007 if (!(p.item is WorkshopItem workshopItem) || !workshopItem.previewImage || workshopItem.previewImage.width <= 2)
1008 {
1009 return null;
1010 }
1011 return workshopItem.previewImage;
1012 }
1013
1015 {
1016 return list.items.OfType<BaseModPackage>().FirstOrDefault() ?? manager.packages.FirstOrDefault();
1017 }
1018
1019 private void ShowInfo(BaseModPackage p)
1020 {
1021 if (p == null || p == panelTarget)
1022 {
1023 return;
1024 }
1025 panelTarget = p;
1026 UIText text = infoTitle.text1;
1027 text.SetText(p.title.IsEmpty(p.dirInfo.Name));
1028 TextGenerationSettings generationSettings = text.GetGenerationSettings(new Vector2(text.rectTransform.rect.width, 0f));
1029 generationSettings.horizontalOverflow = HorizontalWrapMode.Wrap;
1030 TextGenerator cachedTextGeneratorForLayout = text.cachedTextGeneratorForLayout;
1031 cachedTextGeneratorForLayout.Populate(text.text, generationSettings);
1032 if (cachedTextGeneratorForLayout.lineCount < 2)
1033 {
1034 text.text += "\n";
1035 }
1036 if (cachedTextGeneratorForLayout.lineCount > 2)
1037 {
1038 string text2 = text.text;
1039 int num = cachedTextGeneratorForLayout.lines[2].startCharIdx;
1040 do
1041 {
1042 int length = --num - 0;
1043 string str = (text.text = text2.Substring(0, length).TrimEnd() + "..");
1044 cachedTextGeneratorForLayout.Populate(str, generationSettings);
1045 }
1046 while (num > 1 && cachedTextGeneratorForLayout.lineCount > 2);
1047 }
1048 PreviewEntry thumb = GetThumb(p);
1049 infoPreview.SetActive(enable: true);
1050 infoPreview.image1.sprite = thumb.sprite ?? spriteNoPreview;
1051 Image image = infoPreview.image1;
1052 Vector2 size = image.sprite.rect.size;
1053 infoPreview.image2.rectTransform.sizeDelta = size * Mathf.Min(image.rectTransform.rect.width / size.x, image.rectTransform.rect.height / size.y) + Vector2.one * 18f;
1054 SetTopic(infoAuthor, p.author.IsEmpty("-"), null);
1055 SetTopic(infoVersion, p.version.IsEmpty("-"), null);
1056 SetTopic(infoId, p.id, null);
1057 string text4 = ModLoadOrderPreset.WorkshopId(p);
1058 SetTopic(infoWorkshop, text4.IsEmpty() ? p.dirInfo.Name : text4, text4.IsEmpty() ? "mod_filter_local" : "mod_filter_workshop");
1059 SetTopic(infoStatus, (!p.builtin && !p.willActivate) ? "mod_filter_disabled".lang() : null, null);
1060 List<string> list = new List<string>();
1061 if (p.blockedBy != null)
1062 {
1063 list.Add("mod_info_blocked".lang(p.blockedBy.title.IsEmpty(p.blockedBy.id)));
1064 }
1065 if (!p.langDepError.IsEmpty())
1066 {
1067 string[] array = p.langDepError.Split('\t');
1068 list.Add(array[0].lang(string.Join("mod_info_or".lang(), array, 1, array.Length - 1)));
1069 }
1070 if (p.duplicateOf != null)
1071 {
1072 list.Add("mod_info_duplicate".lang(p.duplicateOf.title.IsEmpty(p.duplicateOf.dirInfo?.Name).IsEmpty(p.duplicateOf.id)));
1073 }
1074 if (!p.IsValidVersion())
1075 {
1076 list.Add("mod_info_old_version".lang(p.version, ELayer.core.versionMod.GetText()));
1077 }
1078 if (!p.parseError.IsEmpty())
1079 {
1080 list.Add("mod_info_parse_error".lang(p.parseError));
1081 }
1082 SetInfo(infoProblems, string.Join("\n", list));
1084 string[] tags = p.tags;
1085 SetTopic(item, (tags != null && tags.Length > 0) ? string.Join(", ", p.tags) : null, null);
1086 SetTopic(infoRequires, IdList(p.dependency, alternatives: true), null);
1087 SetTopic(infoIncompatible, IdList(p.incompatible, alternatives: false), null);
1088 SetTopic(infoLoadAfter, IdList(p.loadAfter, alternatives: false), null);
1089 SetTopic(infoLoadBefore, IdList(p.loadBefore, alternatives: false), null);
1090 infoSpace.SetActive(!p.description.IsEmpty());
1091 SetInfo(infoDescription, p.description);
1092 panelNote.Build();
1093 panelScroll.content.anchoredPosition = Vector2.zero;
1094 static string IdList(string[][] rows, bool alternatives)
1095 {
1096 if (rows == null)
1097 {
1098 return null;
1099 }
1100 string sep = (alternatives ? "mod_info_or".lang() : "\n");
1101 return string.Join("\n", from row in rows
1102 where row != null && row.Length > 0
1103 select string.Join(sep, row.Where((string id) => !id.IsEmpty())) into line
1104 where !line.IsEmpty()
1105 select line);
1106 }
1107 static void SetInfo(UIItem uIItem, string value)
1108 {
1109 uIItem.SetActive(!value.IsEmpty());
1110 if (!value.IsEmpty())
1111 {
1112 uIItem.text1.SetText(value);
1113 }
1114 }
1115 static void SetTopic(UIItem uIItem, string value, string lang)
1116 {
1117 uIItem.SetActive(!value.IsEmpty());
1118 if (!value.IsEmpty())
1119 {
1120 if (lang != null)
1121 {
1122 uIItem.text1.SetText(lang.lang());
1123 }
1124 uIItem.text2.SetText(value);
1125 }
1126 }
1127 }
1128
1130 {
1131 SE.Click();
1132 ModPreview.PreviewType kind;
1133 bool owns;
1134 Texture2D tex = LoadPreviewTexture(a, mipmap: false, out kind, out owns);
1135 if (!tex)
1136 {
1137 SE.BeepSmall();
1138 ELayer.ui.Say("mod_preview_unsupported");
1139 return;
1140 }
1141 Sprite image = tex.ToSprite();
1142 LayerImage layerImage = ELayer.ui.AddLayer<LayerImage>();
1143 layerImage.SetImage(image);
1144 layerImage.SetOnKill(delegate
1145 {
1146 UnityEngine.Object.Destroy(tex);
1147 if (owns)
1148 {
1149 UnityEngine.Object.Destroy(tex);
1150 }
1151 });
1152 }
1153
1154 private void ShowPresetMenu()
1155 {
1156 SE.Click();
1158 {
1159 Dialog.Ok("mod_preset_disabled");
1160 return;
1161 }
1162 UIContextMenu uIContextMenu = ELayer.ui.CreateContextMenu();
1163 uIContextMenu.AddButton("mod_preset_save", SavePreset);
1164 uIContextMenu.AddButton("mod_preset_load", delegate
1165 {
1167 });
1168 uIContextMenu.AddButton("mod_preset_delete", delegate
1169 {
1171 });
1172 uIContextMenu.AddButton("mod_preset_copy", CopyPreset);
1173 uIContextMenu.AddButton("mod_preset_paste", PastePreset);
1174 uIContextMenu.AddButton("mod_preset_folder", delegate
1175 {
1176 Directory.CreateDirectory(CorePath.PathLoadOrderPreset);
1177 Util.ShowExplorer(CorePath.PathLoadOrderPreset, selectFirstFile: true);
1178 });
1179 uIContextMenu.Show();
1180 }
1181
1182 private void SavePreset()
1183 {
1184 Dialog.InputName("mod_preset_name", "mod_preset_default_name".lang(), delegate(bool cancel, string text)
1185 {
1186 if (!cancel)
1187 {
1188 string name = (text ?? "").Trim().SanitizeFileName().Trim();
1189 if (name.IsEmpty())
1190 {
1191 SE.BeepSmall();
1192 }
1193 else if (File.Exists(ModManager.GetPresetPath(name)))
1194 {
1195 Dialog.YesNo("mod_preset_overwrite".lang(name), delegate
1196 {
1197 WritePreset(name);
1198 });
1199 }
1200 else
1201 {
1202 WritePreset(name);
1203 }
1204 }
1205 });
1206 }
1207
1208 private void WritePreset(string name)
1209 {
1210 if (!manager.SavePreset(name, out var _))
1211 {
1212 SE.BeepSmall();
1213 return;
1214 }
1215 SE.Click();
1216 ELayer.ui.Say("mod_preset_saved".lang(name));
1217 }
1218
1219 private void SelectPreset(Action<FileInfo> onSelect)
1220 {
1221 List<FileInfo> files = manager.ListPresets();
1222 if (files.Count == 0)
1223 {
1224 Dialog.Ok("mod_preset_none");
1225 return;
1226 }
1227 Dialog.List("mod_preset_select", files, (FileInfo f) => Path.GetFileNameWithoutExtension(f.Name), delegate(int i, string _)
1228 {
1229 onSelect(files[i]);
1230 return true;
1231 }, canCancel: true);
1232 }
1233
1234 private void ApplyPresetFile(FileInfo file)
1235 {
1236 if (!manager.TryLoadPresetFile(file, out var preset, out var _))
1237 {
1238 Dialog.Ok("mod_preset_invalid");
1239 }
1240 else
1241 {
1242 ConfirmPreset(preset);
1243 }
1244 }
1245
1246 private void DeletePreset(FileInfo file)
1247 {
1248 string name = Path.GetFileNameWithoutExtension(file.Name);
1249 Dialog.YesNo("mod_preset_delete_confirm".lang(name), delegate
1250 {
1251 if (file.Exists)
1252 {
1253 file.Delete();
1254 }
1255 SE.Trash();
1256 ELayer.ui.Say("mod_preset_deleted".lang(name));
1257 });
1258 }
1259
1260 private void CopyPreset()
1261 {
1262 ModLoadOrderPreset.Preset preset = ModLoadOrderPreset.Save(manager.packages, "", ELayer.core.version.GetText());
1263 if (preset.entries.Count == 0)
1264 {
1265 SE.BeepSmall();
1266 return;
1267 }
1268 GUIUtility.systemCopyBuffer = ModLoadOrderPreset.Serialize(preset);
1269 SE.Click();
1270 ELayer.ui.Say("mod_preset_copied");
1271 }
1272
1273 private void PastePreset()
1274 {
1275 if (!ModLoadOrderPreset.TryParse(GUIUtility.systemCopyBuffer, out var preset, out var _))
1276 {
1277 Dialog.Ok("mod_preset_invalid");
1278 return;
1279 }
1280 if (preset.name.IsEmpty())
1281 {
1282 preset.name = "mod_preset_default_name".lang();
1283 }
1284 ConfirmPreset(preset);
1285 }
1286
1287 private void ConfirmPreset(ModLoadOrderPreset.Preset preset)
1288 {
1289 List<ModLoadOrderPreset.Entry> list = ModLoadOrderPreset.FindMissing(manager.packages, preset);
1290 if (list.Count == 0)
1291 {
1292 ApplyPreset(preset);
1293 return;
1294 }
1295 Dialog.YesNo("mod_preset_missing".lang(DescribeEntries(list, 15)), delegate
1296 {
1297 ApplyPreset(preset);
1298 }, null, "mod_preset_apply", "cancel");
1299 }
1300
1301 private static string DescribeEntries(List<ModLoadOrderPreset.Entry> entries, int max)
1302 {
1303 StringBuilder stringBuilder = new StringBuilder();
1304 for (int i = 0; i < entries.Count && i < max; i++)
1305 {
1306 ModLoadOrderPreset.Entry entry = entries[i];
1307 stringBuilder.Append(entry.title.IsEmpty() ? entry.id : (entry.title + " (" + entry.id + ")")).Append('\n');
1308 }
1309 if (entries.Count > max)
1310 {
1311 stringBuilder.Append("mod_preset_more".lang((entries.Count - max).ToString() ?? "")).Append('\n');
1312 }
1313 return stringBuilder.ToString().TrimEnd();
1314 }
1315
1316 private void ApplyPreset(ModLoadOrderPreset.Preset preset)
1317 {
1318 if (HasFilter)
1319 {
1320 ClearSearch();
1321 }
1322 ModLoadOrderPreset.ApplyResult applyResult = manager.ApplyPreset(preset);
1323 SE.Tab();
1324 textRestart.SetActive(enable: true);
1325 RefreshLists();
1326 string text = ELayer.core.version.GetText();
1327 if (!preset.gameVersion.IsEmpty() && preset.gameVersion != text)
1328 {
1329 ELayer.ui.Say("mod_preset_version_warn".lang(preset.gameVersion, text));
1330 }
1331 ELayer.ui.Say("mod_preset_applied".lang(preset.name, applyResult.enabled.ToString() ?? "", applyResult.missing.Count.ToString() ?? ""));
1332 }
1333
1334 public void Refresh()
1335 {
1336 }
1337
1338 public override void OnKill()
1339 {
1340 if ((bool)TooltipManager.Instance)
1341 {
1342 TooltipManager.Instance.HideTooltips(immediate: true);
1343 }
1344 foreach (PreviewEntry value in previews.Values)
1345 {
1346 if ((bool)value.sprite)
1347 {
1348 if (value.ownsTexture)
1349 {
1350 UnityEngine.Object.Destroy(value.sprite.texture);
1351 }
1352 UnityEngine.Object.Destroy(value.sprite);
1353 }
1354 }
1355 previews.Clear();
1357 if (Instance == this)
1358 {
1359 Instance = null;
1360 }
1361 }
1362}
if(!match.Success)
FontColor
Definition: FontColor.cs:2
PickerState
Definition: PickerState.cs:2
item3. title
Definition: UIBook.cs:640
static bool IsOffline
Definition: BaseCore.cs:9
Version versionMod
Definition: BaseCore.cs:21
Version version
Definition: BaseCore.cs:17
UIList.ICallback callbacks
Definition: BaseList.cs:13
static string rootMod
DirectoryInfo dirInfo
string[][] loadAfter
BaseModPackage duplicateOf
void UpdateMeta(bool updateOnly=false)
string[][] loadBefore
string[][] dependency
BaseModPackage blockedBy
string[][] incompatible
void Save()
Definition: CoreConfig.cs:852
OtherSetting other
Definition: CoreConfig.cs:639
bool enable
Definition: CoreDebug.cs:302
static string PathLoadOrderPreset
Definition: CorePath.cs:208
Definition: Core.cs:14
ModManager mods
Definition: Core.cs:39
static void TryWarnUpload(Action action)
Definition: Core.cs:859
static float delta
Definition: Core.cs:17
Definition: Dialog.cs:7
static Dialog YesNo(string langDetail, Action actionYes, Action actionNo=null, string langYes="yes", string langNo="no")
Definition: Dialog.cs:252
static Dialog InputName(string langDetail, string text, Action< bool, string > onClose, InputType inputType=InputType.Default)
Definition: Dialog.cs:536
static Dialog Ok(string langDetail, Action action=null)
Definition: Dialog.cs:230
Definition: ELayer.cs:4
static Core core
Definition: ELayer.cs:7
static CoreDebug debug
Definition: ELayer.cs:43
static CoreConfig config
Definition: ELayer.cs:31
static UI ui
Definition: ELayer.cs:21
UIButton buttonConfig
Definition: ItemMod.cs:23
Image imageMember
Definition: ItemMod.cs:31
UIButton buttonColor
Definition: ItemMod.cs:21
UIButton buttonRename
Definition: ItemMod.cs:17
UIButton buttonActivate
Definition: ItemMod.cs:5
Image imageGroup
Definition: ItemMod.cs:29
UIButton buttonUp
Definition: ItemMod.cs:11
UIButton buttonToggle
Definition: ItemMod.cs:15
UIButton buttonDown
Definition: ItemMod.cs:13
UIButton buttonDisband
Definition: ItemMod.cs:19
UIButton buttonLock
Definition: ItemMod.cs:9
Definition: Lang.cs:7
static string langCode
Definition: Lang.cs:29
void SetImage(Sprite sprite)
Definition: LayerImage.cs:12
static void Open(ModPackage p)
void OnPointerEnter(PointerEventData eventData)
Definition: LayerMod.cs:26
ModPreview.PreviewType kind
Definition: LayerMod.cs:19
void AddGroupButtons(UIContextMenu m, BaseModPackage a)
Definition: LayerMod.cs:706
const string urlWorkshopItem
Definition: LayerMod.cs:32
IEnumerable< ModGroup > Groups()
Definition: LayerMod.cs:564
void RefreshLists()
Definition: LayerMod.cs:272
UIItem infoPreviewNote
Definition: LayerMod.cs:60
void MoveTo(object row, object target)
Definition: LayerMod.cs:174
void ShowInfo(BaseModPackage p)
Definition: LayerMod.cs:1019
bool HasFilter
Definition: LayerMod.cs:113
UIItem infoProblems
Definition: LayerMod.cs:72
void InputGroupName(string text, Action< string > onInput)
Definition: LayerMod.cs:797
UIItem infoPreview
Definition: LayerMod.cs:58
UIItem infoStatus
Definition: LayerMod.cs:70
void SelectPreset(Action< FileInfo > onSelect)
Definition: LayerMod.cs:1219
UIHeader panelHeader
Definition: LayerMod.cs:52
void ShowPresetMenu()
Definition: LayerMod.cs:1154
UIButton buttonFilter
Definition: LayerMod.cs:90
bool Match(BaseModPackage p)
Definition: LayerMod.cs:833
void PastePreset()
Definition: LayerMod.cs:1273
bool wasSearchFocused
Definition: LayerMod.cs:98
UIItem infoIncompatible
Definition: LayerMod.cs:78
string lastSearch
Definition: LayerMod.cs:100
UIList list
Definition: LayerMod.cs:36
ModManager manager
Definition: LayerMod.cs:110
UIButton buttonClearSearch
Definition: LayerMod.cs:46
static Texture2D LoadPreviewTexture(BaseModPackage p, bool mipmap, out ModPreview.PreviewType kind, out bool owns)
Definition: LayerMod.cs:973
UIItem infoWorkshop
Definition: LayerMod.cs:68
UIItem infoDescription
Definition: LayerMod.cs:84
UIItem infoTitle
Definition: LayerMod.cs:56
void CopyPreset()
Definition: LayerMod.cs:1260
string[] searchTerms
Definition: LayerMod.cs:102
int GetGroupIndex(BaseModPackage anchor, bool last)
Definition: LayerMod.cs:594
void RefreshFilterButton()
Definition: LayerMod.cs:908
void LateUpdate()
Definition: LayerMod.cs:930
ModSearch.Filter filterMode
Definition: LayerMod.cs:104
void NewGroup()
Definition: LayerMod.cs:600
UIButton toggleDisableMods
Definition: LayerMod.cs:44
override void OnInit()
Definition: LayerMod.cs:287
void Search(string s)
Definition: LayerMod.cs:862
override void OnKill()
Definition: LayerMod.cs:1338
void ApplyPreset(ModLoadOrderPreset.Preset preset)
Definition: LayerMod.cs:1316
PreviewEntry GetThumb(BaseModPackage p)
Definition: LayerMod.cs:954
UIItem infoTags
Definition: LayerMod.cs:74
BaseModPackage panelTarget
Definition: LayerMod.cs:94
UIItem infoLoadAfter
Definition: LayerMod.cs:80
void OnReorder(bool restart=true)
Definition: LayerMod.cs:260
Sprite spriteNoPreview
Definition: LayerMod.cs:88
void ShowPreview(BaseModPackage a)
Definition: LayerMod.cs:1129
UIItem infoVersion
Definition: LayerMod.cs:64
void ClearSearchText()
Definition: LayerMod.cs:872
void CollapseAll()
Definition: LayerMod.cs:781
static string FilterLabel(ModSearch.Filter f)
Definition: LayerMod.cs:917
static Texture2D SteamPreview(BaseModPackage p)
Definition: LayerMod.cs:1005
void Move(object row, int a)
Definition: LayerMod.cs:124
void SetModRow(ModPackage a, ItemMod b)
Definition: LayerMod.cs:404
UIList.Callback< object, ItemMod > CreateCallbacks(UIList target, bool builtin)
Definition: LayerMod.cs:326
UIList list2
Definition: LayerMod.cs:38
void ApplyPresetFile(FileInfo file)
Definition: LayerMod.cs:1234
InputField inputSearch
Definition: LayerMod.cs:48
UIText textRestart
Definition: LayerMod.cs:40
float timerSearch
Definition: LayerMod.cs:96
static string FitTitle(UIText text, string title, string suffix="")
Definition: LayerMod.cs:816
UIItem infoId
Definition: LayerMod.cs:66
readonly Dictionary< BaseModPackage, string > searchCache
Definition: LayerMod.cs:106
void CycleFilter()
Definition: LayerMod.cs:900
void InitSearchUI()
Definition: LayerMod.cs:842
UIItem infoLoadBefore
Definition: LayerMod.cs:82
void Refresh()
Definition: LayerMod.cs:1334
void SavePreset()
Definition: LayerMod.cs:1182
UIButton buttonCollapse
Definition: LayerMod.cs:92
void WritePreset(string name)
Definition: LayerMod.cs:1208
static string DescribeEntries(List< ModLoadOrderPreset.Entry > entries, int max)
Definition: LayerMod.cs:1301
void SetGroup(BaseModPackage p, ModGroup g)
Definition: LayerMod.cs:742
GameObject infoSpace
Definition: LayerMod.cs:86
readonly Dictionary< BaseModPackage, PreviewEntry > previews
Definition: LayerMod.cs:108
void DeletePreset(FileInfo file)
Definition: LayerMod.cs:1246
void SetGroupRow(ModGroup g, ItemMod b)
Definition: LayerMod.cs:626
void ClearSearch()
Definition: LayerMod.cs:882
void ConfirmPreset(ModLoadOrderPreset.Preset preset)
Definition: LayerMod.cs:1287
UINote panelNote
Definition: LayerMod.cs:54
BaseModPackage FirstInfoTarget()
Definition: LayerMod.cs:1014
UIItem infoRequires
Definition: LayerMod.cs:76
UIItem infoAuthor
Definition: LayerMod.cs:62
List< BaseModPackage > Members(ModGroup g)
Definition: LayerMod.cs:559
UIScrollView panelScroll
Definition: LayerMod.cs:50
void SetMembersActive(ModGroup g, bool active)
Definition: LayerMod.cs:572
static LayerMod Instance
Definition: LayerMod.cs:34
void LeaveGroup(BaseModPackage p)
Definition: LayerMod.cs:584
UIText textNoResult
Definition: LayerMod.cs:42
List< Window > windows
Definition: Layer.cs:116
Layer SetOnKill(Action action)
Definition: Layer.cs:584
Color? color
Definition: ModGroup.cs:10
BaseModPackage after
Definition: ModGroup.cs:12
bool collapsed
Definition: ModGroup.cs:8
string name
Definition: ModGroup.cs:6
bool TryLoadPresetFile(FileInfo file, out ModLoadOrderPreset.Preset preset, out string error)
Definition: ModManager.cs:314
ModLoadOrderPreset.ApplyResult ApplyPreset(ModLoadOrderPreset.Preset preset, bool disableOthers=true)
Definition: ModManager.cs:338
static string GetPresetPath(string name)
Definition: ModManager.cs:287
static bool disableMod
Definition: ModManager.cs:41
ModPackage AddPackage(DirectoryInfo dir, bool isInPackages=false)
Definition: ModManager.cs:424
readonly List< ModGroup > emptyGroups
Definition: ModManager.cs:47
bool SavePreset(string name, out string path)
Definition: ModManager.cs:301
void SaveLoadOrder()
Definition: ModManager.cs:106
List< FileInfo > ListPresets()
Definition: ModManager.cs:292
void CopyContentTo(string dir)
Definition: ModPackage.cs:25
override string UpdateSourceLocalizationFile(string lang, bool force=false)
Definition: ModPackage.cs:349
Action< UINote > onBuildConfig
Definition: ModPackage.cs:19
static TooltipManager Instance
void HideTooltips(bool immediate=false)
void SetCheck(bool check)
Definition: UIButton.cs:332
UIText mainText
Definition: UIButton.cs:102
void SetToggle(bool isOn, Action< bool > onToggle=null)
Definition: UIButton.cs:341
void Show(UIItem i)
void AddButton(Func< string > funcText, UnityAction action=null)
Definition: UIItem.cs:5
UIButton button1
Definition: UIItem.cs:18
Image image1
Definition: UIItem.cs:14
UIText text2
Definition: UIItem.cs:8
UIText text1
Definition: UIItem.cs:6
Definition: UIList.cs:9
List< object > items
Definition: UIList.cs:273
UIScrollView dragScrollView
Definition: UIList.cs:313
override void Add(object item)
Definition: UIList.cs:357
ButtonPair GetPair(object item)
Definition: UIList.cs:370
override void List()
Definition: UIList.cs:773
Definition: UINote.cs:6
void Build()
Definition: UINote.cs:49
Definition: UIText.cs:6
void SetText(string s)
Definition: UIText.cs:163
Component component
Definition: UIList.cs:216
string GetText()
Definition: Version.cs:34
bool demo
Definition: Version.cs:15