diff --git a/Assemblies/Diary.dll b/Assemblies/Diary.dll index e0502f5..f4aa3bf 100644 Binary files a/Assemblies/Diary.dll and b/Assemblies/Diary.dll differ diff --git a/Source/DiaryService.cs b/Source/DiaryService.cs index 3e8e280..4b2de9e 100644 --- a/Source/DiaryService.cs +++ b/Source/DiaryService.cs @@ -3,6 +3,7 @@ using System.IO; using System.IO.Packaging; using System.Xml; +using HarmonyLib; using RimWorld; using RTFExporter; using Verse; @@ -12,10 +13,12 @@ namespace Diary public class DiaryService : GameComponent { private Dictionary entries; + private Dictionary> images; public DiaryService(Game game) { entries = new Dictionary(); + images = new Dictionary>(); } private string[] GetTextEntriesToExport() @@ -130,6 +133,28 @@ public void AppendEntryNow(string data, bool onNewLine = true, bool writeCurrent entries.SetOrAdd(key, $"{entries[key]}{data}"); } + public List ReadImages(int day, Quadrum quadrum, int year) + { + DefaultMessage defaultMessageSetting = LoadedModManager.GetMod().GetSettings().DefaultMessage; + + return images.TryGetValue(GetDictionaryKey(day, quadrum, year)); + } + + public void AddImageNow(string path) + { + string key = GetDictionaryKey(TimeTools.GetCurrentDay(), TimeTools.GetCurrentQuadrum(), TimeTools.GetCurrentYear()); + List currentImages = images.TryGetValue(key); + + if (currentImages == null) + { + currentImages = new List(); + } + + currentImages.Add(new DiaryImageEntry(path, TimeTools.GetCurrentHour())); + + images.SetOrAdd(key, currentImages); + } + public void Export() { string folder = LoadedModManager.GetMod().GetSettings().FolderPath; diff --git a/Source/DiaryTypes.cs b/Source/DiaryTypes.cs index dd06522..7a6f38f 100644 --- a/Source/DiaryTypes.cs +++ b/Source/DiaryTypes.cs @@ -85,4 +85,16 @@ public static string GetLogWriterFilterName(LogWriterFilter f) } } } + + public class DiaryImageEntry + { + public string Path; + public int Hours; + + public DiaryImageEntry(string path, int hours) + { + Path = path; + Hours = hours; + } + } } diff --git a/Source/GUIDraggableTexture.cs b/Source/GUIDraggableTexture.cs new file mode 100644 index 0000000..3b10063 --- /dev/null +++ b/Source/GUIDraggableTexture.cs @@ -0,0 +1,212 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +using UnityEngine; +using HarmonyLib; +using RimWorld; +using Verse; +using Verse.AI; +using Verse.Sound; +using RimWorld.Planet; +using UnityEngine.Networking; +using System.Windows; +using Rect = UnityEngine.Rect; +using Verse.Noise; +using RTFExporter; + +namespace Diary +{ + public class GUIDraggableTexture + { + private const float ZoomRatio = 0.2f; + + private float currentImageScale; + private Rect imageRect; + private int imageWidth; + private int imageHeight; + private Texture2D currentImageDisplayed; + private UnityWebRequest imageLoadRequest; + private bool imageLoading; + private Rect outerRect; + private Rect initialOuterRect; + private bool mustRecomputeOuterRect; + + public GUIDraggableTexture() + { + currentImageScale = 1.0f; + + imageRect = new Rect(0.0f, 0.0f, 1.0f, 1.0f); + mustRecomputeOuterRect = false; + } + + public bool HasImageLoaded() + { + return currentImageDisplayed != null; + } + + public bool IsLoading() + { + return imageLoading; + } + + public void LoadTexture(string path) + { + Log.Message($"Laod {path}"); + imageLoading = true; + imageLoadRequest = UnityWebRequestTexture.GetTexture($"file://{path}"); + + imageLoadRequest.SendWebRequest().completed += delegate + { + currentImageDisplayed = DownloadHandlerTexture.GetContent(imageLoadRequest); + + imageWidth = currentImageDisplayed.width; + imageHeight = currentImageDisplayed.height; + + imageLoading = false; + mustRecomputeOuterRect = true; + }; + } + + private void TryFixImageCoordinates() + { + if (imageRect.xMin < 0f) + { + float diff = imageRect.xMin; + + imageRect.xMin -= diff; + imageRect.xMax -= diff; + } + else if (imageRect.xMax > 1.0f) + { + float diff = imageRect.xMax - 1.0f; + + imageRect.xMin -= diff; + imageRect.xMax -= diff; + } + + if (imageRect.yMin < 0f) + { + float diff = imageRect.yMin; + + imageRect.yMin -= diff; + imageRect.yMax -= diff; + } + else if (imageRect.yMax > 1.0f) + { + float diff = imageRect.yMax - 1.0f; + + imageRect.yMin -= diff; + imageRect.yMax -= diff; + } + } + + private void OnScrollWheel() + { + Event.current.Use(); + + float xRatio = outerRect.width / (float)imageWidth; + float yRatio = outerRect.height / (float)imageHeight; + + if (Event.current.delta.y > 0 && currentImageScale > 1.00f) + { + + imageRect.xMin -= xRatio * ZoomRatio; + imageRect.xMax += xRatio * ZoomRatio; + imageRect.yMin -= yRatio * ZoomRatio; + imageRect.yMax += yRatio * ZoomRatio; + currentImageScale -= 0.1f; + + TryFixImageCoordinates(); + } + else if (Event.current.delta.y < 0 && currentImageScale < 2.0f) + { + + imageRect.xMin += xRatio * ZoomRatio; + imageRect.xMax -= xRatio * ZoomRatio; + imageRect.yMin += yRatio * ZoomRatio; + imageRect.yMax -= yRatio * ZoomRatio; + currentImageScale += 0.1f; + + TryFixImageCoordinates(); + } + } + + private void OnDrag() + { + var currentCenter = imageRect.center; + + float xDiff = Event.current.delta.x * -0.001f / currentImageScale / currentImageScale; + float yDiff = Event.current.delta.y * -0.001f / currentImageScale / currentImageScale; + + if ((xDiff > 0f && imageRect.xMax < 1.0f) || (xDiff < 0f && imageRect.xMin > 0.0f)) + { + currentCenter.x += xDiff; + } + + + if ((yDiff > 0f && imageRect.yMax < 1.0f) || (yDiff < 0f && imageRect.yMin > 0.0f)) + { + currentCenter.y += yDiff; + } + + imageRect.center = currentCenter; + + TryFixImageCoordinates(); + } + + private void ComputeDefaultRects(Rect inRect) + { + outerRect = new Rect(0.0f, inRect.yMin, inRect.width, inRect.height); + initialOuterRect = new Rect(0.0f, inRect.yMin, inRect.width, inRect.height); + + float displayRatio = inRect.width / inRect.height; + float imageRatio = (float)imageWidth / (float)imageHeight; + + if (displayRatio > imageRatio) + { + float updateRatio = imageRatio / displayRatio; + + imageRect = new Rect(0f, (1f - updateRatio) * 0.5f, 1f, updateRatio); + } + else + { + float updateRatio = displayRatio / imageRatio; + + imageRect = new Rect(0.5f - updateRatio * 0.5f, 0f, updateRatio, 1f); + } + + mustRecomputeOuterRect = false; + } + + public void Draw(Rect inRect) + { + if (HasImageLoaded()) + { + if (mustRecomputeOuterRect) + { + ComputeDefaultRects(inRect); + } + + + Widgets.DrawTexturePart(outerRect, imageRect, currentImageDisplayed); + } + if (Mouse.IsOver(outerRect)) + { + if (Event.current.type == EventType.ScrollWheel) + { + OnScrollWheel(); + } + + if (Input.GetMouseButton(0) && Event.current.type == EventType.MouseDrag) + { + OnDrag(); + } + } + } + } +} diff --git a/Source/MainTabWindow_Diary.cs b/Source/MainTabWindow_Diary.cs index be5a202..b500a39 100644 --- a/Source/MainTabWindow_Diary.cs +++ b/Source/MainTabWindow_Diary.cs @@ -13,7 +13,8 @@ using Verse.AI; using Verse.Sound; using RimWorld.Planet; -using static HarmonyLib.Code; +using UnityEngine.Networking; +using Verse.Noise; namespace Diary { @@ -26,6 +27,10 @@ public class MainTabWindow_Diary : MainTabWindow private int displayedMessageIndex = -1; private float messageLastHeight = 0f; private LogFilter logFilter; + private bool imageDisplayMode; + private GUIDraggableTexture draggableImage; + private List dayImages; + private int selectedDayImagesIndex; private readonly List fastHourStrings; private Dictionary truncationCache = new Dictionary(); @@ -80,7 +85,9 @@ public MainTabWindow_Diary() DiarySettings settings = LoadedModManager.GetMod().GetSettings(); + imageDisplayMode = false; logFilter = settings.DefaultLogFilter; + draggableImage = new GUIDraggableTexture(); } public bool CanAccessToPreviousDay() @@ -363,13 +370,36 @@ private void DoLogEntryRow(Rect rect, LogEntry logEntry, int index) } } + public void DoImageDisplayContents(Rect inRect) + { + if (draggableImage.HasImageLoaded()) + { + draggableImage.Draw(inRect); + } + + Widgets.EndGroup(); + } + public override void DoWindowContents(Rect inRect) { Rect dateRect = new Rect(0f, 0f, inRect.width, 40f); float widthPerButton = inRect.width / 5; + Text.Font = GameFont.Small; Widgets.BeginGroup(inRect); + + if (Widgets.ButtonText(new Rect(0.0f, dateRect.yMin, widthPerButton / 2, dateRect.yMax), "IMG")) + { + imageDisplayMode = !imageDisplayMode; + dayImages = Current.Game.GetComponent().ReadImages(this.day, this.quadrum, this.year); + selectedDayImagesIndex = 0; + if (dayImages.Count > 0) + { + draggableImage.LoadTexture(dayImages[0].Path); + } + } + if (CanAccessToPreviousDay()) { if (Widgets.ButtonText(new Rect(widthPerButton * 0.5f, dateRect.yMin, widthPerButton / 2, dateRect.yMax), "<")) @@ -429,6 +459,31 @@ public override void DoWindowContents(Rect inRect) } } + if (imageDisplayMode) + { + DiaryImageEntry d = dayImages[selectedDayImagesIndex]; + + if (d != null && Widgets.ButtonText(new Rect(widthPerButton * 4.5f, dateRect.yMin, widthPerButton / 2, dateRect.yMax), fastHourStrings[d.Hours])) + { + + List list = new List(); + for (int i = 0; i < dayImages.Count; i++) + { + int current = i; + list.Add(new FloatMenuOption(fastHourStrings[dayImages[current].Hours], delegate + { + selectedDayImagesIndex = current; + draggableImage.LoadTexture(dayImages[current].Path); + })); + } + Find.WindowStack.Add(new FloatMenu(list)); + } + + DoImageDisplayContents(new Rect(0f, dateRect.yMax + 10f, inRect.width, inRect.height - dateRect.yMax)); + + return; + } + Rect entryWritingRect = new Rect(0f, dateRect.yMax + 10f, inRect.width, 300f); Current.Game.GetComponent().WriteEntry(Widgets.TextArea(entryWritingRect, Current.Game.GetComponent().ReadEntry(this.day, this.quadrum, this.year)), this.day, this.quadrum, this.year); diff --git a/Source/Patches/ListenProgressRenderer_CreateFilePath.cs b/Source/Patches/ListenProgressRenderer_CreateFilePath.cs new file mode 100644 index 0000000..6c6c1c9 --- /dev/null +++ b/Source/Patches/ListenProgressRenderer_CreateFilePath.cs @@ -0,0 +1,17 @@ +using System.Linq; + +using HarmonyLib; +using Verse; + +namespace Diary +{ + [HarmonyPatch(typeof(ProgressRenderer.MapComponent_RenderManager), "CreateFilePath")] + public static class ListenProgressRenderer_CreateFilePath + { + static void Postfix(ref string __result) + { + Log.Message("Image created"); + Current.Game.GetComponent().AddImageNow(__result); + } + } +} diff --git a/Source/RimworldStories.csproj b/Source/RimworldStories.csproj index 94e0883..733c682 100644 --- a/Source/RimworldStories.csproj +++ b/Source/RimworldStories.csproj @@ -39,6 +39,10 @@ ..\..\..\RimWorldWin64_Data\Managed\Assembly-CSharp.dll False + + ..\..\..\dlldeps\Progress-Renderer.dll + False + @@ -63,6 +67,14 @@ ..\..\..\RimWorldWin64_Data\Managed\UnityEngine.IMGUIModule.dll False + + ..\..\..\RimWorldWin64_Data\Managed\UnityEngine.InputLegacyModule.dll + False + + + ..\..\..\RimWorldWin64_Data\Managed\UnityEngine.InputModule.dll + False + ..\..\..\RimWorldWin64_Data\Managed\UnityEngine.ScreenCaptureModule.dll False @@ -79,13 +91,27 @@ ..\..\..\RimWorldWin64_Data\Managed\UnityEngine.UI.dll False + + ..\..\..\RimWorldWin64_Data\Managed\UnityEngine.UnityWebRequestModule.dll + False + + + ..\..\..\RimWorldWin64_Data\Managed\UnityEngine.UnityWebRequestTextureModule.dll + False + + + ..\..\..\RimWorldWin64_Data\Managed\UnityEngine.UnityWebRequestWWWModule.dll + False + + +