diff --git a/src/TSMapEditor/Rendering/MapView.cs b/src/TSMapEditor/Rendering/MapView.cs index 3bd1b362..9ba0d572 100644 --- a/src/TSMapEditor/Rendering/MapView.cs +++ b/src/TSMapEditor/Rendering/MapView.cs @@ -120,8 +120,6 @@ public MapView(WindowManager windowManager, Map map, TheaterGraphics theaterGrap private ulong refreshIndex; - private bool debugRenderDepthBuffer = false; - private AircraftRenderer aircraftRenderer; private AnimRenderer animRenderer; private BuildingRenderer buildingRenderer; diff --git a/src/TSMapEditor/Settings/RecentFiles.cs b/src/TSMapEditor/Settings/RecentFiles.cs new file mode 100644 index 00000000..1cf31695 --- /dev/null +++ b/src/TSMapEditor/Settings/RecentFiles.cs @@ -0,0 +1,71 @@ +using Rampastring.Tools; +using System.Collections.Generic; +using System.Globalization; +using TSMapEditor.Misc; + +namespace TSMapEditor.Settings +{ + public class RecentFiles + { + public const int MaxEntries = 4; + private const string IniSectionName = "RecentFiles"; + + private List entries = new List(MaxEntries); + + public void PutEntry(string entry) + { + int existingIndex = entries.IndexOf(entry); + if (existingIndex == 0) + return; + + if (existingIndex > -1) + { + entries.Swap(0, existingIndex); + } + else + { + entries.Insert(0, entry); + TrimEntries(); + } + } + + public List GetEntries() => new List(entries); + + private void TrimEntries() + { + if (entries.Count > MaxEntries) + entries.RemoveRange(MaxEntries, entries.Count - MaxEntries); + } + + public void WriteToIniFile(IniFile iniFile) + { + iniFile.RemoveSection(IniSectionName); + + if (entries.Count == 0) + return; + + var section = new IniSection(IniSectionName); + for (int i = 0; i < entries.Count; i++) + { + section.AddKey(i.ToString(CultureInfo.InvariantCulture), entries[i]); + } + iniFile.AddSection(section); + } + + public void ReadFromIniFile(IniFile iniFile) + { + var keys = iniFile.GetSectionKeys(IniSectionName); + if (keys == null) + return; + + foreach (string key in keys) + { + string path = iniFile.GetStringValue(IniSectionName, key, string.Empty); + if (!string.IsNullOrWhiteSpace(path)) + entries.Add(path); + } + + TrimEntries(); + } + } +} diff --git a/src/TSMapEditor/Settings/UserSettings.cs b/src/TSMapEditor/Settings/UserSettings.cs index 315f7986..e824b51d 100644 --- a/src/TSMapEditor/Settings/UserSettings.cs +++ b/src/TSMapEditor/Settings/UserSettings.cs @@ -47,6 +47,8 @@ public UserSettings() foreach (var setting in settings) setting.LoadValue(UserSettingsIni); + + RecentFiles.ReadFromIniFile(UserSettingsIni); } public IniFile UserSettingsIni { get; } @@ -58,6 +60,8 @@ public void SaveSettings() setting.WriteValue(UserSettingsIni, false); } + RecentFiles.WriteToIniFile(UserSettingsIni); + UserSettingsIni.WriteIniFile(); } @@ -92,5 +96,7 @@ public async Task SaveSettingsAsync() public StringSetting LastScenarioPath = new StringSetting(General, nameof(LastScenarioPath), "Maps/Custom/"); public StringSetting TextEditorPath = new StringSetting(General, "TextEditorPath", string.Empty); + + public RecentFiles RecentFiles = new RecentFiles(); } } diff --git a/src/TSMapEditor/UI/MainMenu.cs b/src/TSMapEditor/UI/MainMenu.cs index 6ad30549..f24d6bd6 100644 --- a/src/TSMapEditor/UI/MainMenu.cs +++ b/src/TSMapEditor/UI/MainMenu.cs @@ -41,8 +41,11 @@ public MainMenu(WindowManager windowManager) : base(windowManager) public override void Initialize() { + bool hasRecentFiles = UserSettings.Instance.RecentFiles.GetEntries().Count > 0; + Name = nameof(MainMenu); Width = 570; + Height = WindowManager.RenderResolutionY; var lblGameDirectory = new XNALabel(WindowManager); lblGameDirectory.Name = nameof(lblGameDirectory); @@ -122,17 +125,38 @@ public override void Initialize() lbFileList.Name = nameof(lbFileList); lbFileList.X = Constants.UIEmptySideSpace; lbFileList.Y = lblDirectoryListing.Bottom + Constants.UIVerticalSpacing; - lbFileList.Width = Width - Constants.UIEmptySideSpace * 2; + lbFileList.Width = Width - (Constants.UIEmptySideSpace * 2); lbFileList.Height = 420; lbFileList.FileSelected += LbFileList_FileSelected; lbFileList.FileDoubleLeftClick += LbFileList_FileDoubleLeftClick; AddChild(lbFileList); + if (hasRecentFiles) + { + const int recentFilesHeight = 150; + lbFileList.Height -= recentFilesHeight + Constants.UIVerticalSpacing; + + var lblRecentFiles = new XNALabel(WindowManager); + lblRecentFiles.Name = nameof(lblRecentFiles); + lblRecentFiles.X = lbFileList.X; + lblRecentFiles.Y = lbFileList.Bottom + Constants.UIVerticalSpacing; + lblRecentFiles.Text = "Recent files:"; + AddChild(lblRecentFiles); + + var recentFilesPanel = new RecentFilesPanel(WindowManager); + recentFilesPanel.X = lblRecentFiles.X; + recentFilesPanel.Y = lblRecentFiles.Bottom + Constants.UIVerticalSpacing; + recentFilesPanel.Width = lbFileList.Width; + recentFilesPanel.Height = recentFilesHeight - lblRecentFiles.Height - (Constants.UIVerticalSpacing * 2); + recentFilesPanel.FileSelected += RecentFilesPanel_FileSelected; + AddChild(recentFilesPanel); + } + btnLoad = new EditorButton(WindowManager); btnLoad.Name = nameof(btnLoad); btnLoad.Width = 150; btnLoad.Text = "Load"; - btnLoad.Y = lbFileList.Bottom + Constants.UIEmptyTopSpace; + btnLoad.Y = Height - btnLoad.Height - Constants.UIEmptyBottomSpace; btnLoad.X = lbFileList.Right - btnLoad.Width; AddChild(btnLoad); btnLoad.LeftClick += BtnLoad_LeftClick; @@ -146,7 +170,13 @@ public override void Initialize() AddChild(btnCreateNewMap); btnCreateNewMap.LeftClick += BtnCreateNewMap_LeftClick; - Height = btnLoad.Bottom + Constants.UIEmptyBottomSpace; + var lblCopyright = new XNALabel(WindowManager); + lblCopyright.Name = nameof(lblCopyright); + lblCopyright.Text = "Created by Rampastring"; + lblCopyright.TextColor = UISettings.ActiveSettings.SubtleTextColor; + AddChild(lblCopyright); + lblCopyright.CenterOnControlVertically(btnCreateNewMap); + lblCopyright.X = btnCreateNewMap.Right + ((btnLoad.X - btnCreateNewMap.Right) - lblCopyright.Width) / 2; settingsPanel = new SettingsPanel(WindowManager); settingsPanel.Name = nameof(settingsPanel); @@ -191,6 +221,12 @@ public override void Initialize() } } + private void RecentFilesPanel_FileSelected(object sender, FileSelectedEventArgs e) + { + tbMapPath.Text = e.FilePath; + BtnLoad_LeftClick(this, EventArgs.Empty); + } + private void LbFileList_FileSelected(object sender, FileSelectionEventArgs e) { tbMapPath.Text = e.FilePath; @@ -290,18 +326,13 @@ private void ApplySettings() UserSettings.Instance.GameDirectory.UserDefinedValue = tbGameDirectory.Text; UserSettings.Instance.LastScenarioPath.UserDefinedValue = tbMapPath.Text; + UserSettings.Instance.RecentFiles.PutEntry(tbMapPath.Text); bool fullscreenWindowed = UserSettings.Instance.FullscreenWindowed.GetValue(); bool borderless = UserSettings.Instance.Borderless.GetValue(); if (fullscreenWindowed && !borderless) throw new InvalidOperationException("Borderless= cannot be set to false if FullscreenWindowed= is enabled."); - var gameForm = (System.Windows.Forms.Form)System.Windows.Forms.Form.FromHandle(Game.Window.Handle); - - double renderScale = UserSettings.Instance.RenderScale.GetValue(); - - - WindowManager.CenterControlOnScreen(this); _ = UserSettings.Instance.SaveSettingsAsync(); @@ -337,6 +368,7 @@ private void BtnBrowseMapPath_LeftClick(object sender, EventArgs e) if (openFileDialog.ShowDialog() == DialogResult.OK) { tbMapPath.Text = openFileDialog.FileName; + BtnLoad_LeftClick(this, new EventArgs()); } } #endif diff --git a/src/TSMapEditor/UI/RecentFilesPanel.cs b/src/TSMapEditor/UI/RecentFilesPanel.cs new file mode 100644 index 00000000..f846c353 --- /dev/null +++ b/src/TSMapEditor/UI/RecentFilesPanel.cs @@ -0,0 +1,57 @@ +using Rampastring.XNAUI; +using Rampastring.XNAUI.XNAControls; +using System; +using System.Collections.Generic; +using System.Globalization; +using TSMapEditor.Settings; +using TSMapEditor.UI.Windows; + +namespace TSMapEditor.UI +{ + public class RecentFilesPanel : XNAPanel + { + public RecentFilesPanel(WindowManager windowManager) : base(windowManager) + { + BackgroundTexture = AssetLoader.CreateTexture(UISettings.ActiveSettings.BackgroundColor, 2, 2); + } + + public EventHandler FileSelected; + + private List fileLabels = new List(); + + public override void Initialize() + { + Name = nameof(RecentFilesPanel); + + var entries = UserSettings.Instance.RecentFiles.GetEntries(); + + int y = Constants.UIEmptyTopSpace; + + for (int i = 0; i < entries.Count; i++) + { + string path = entries[i]; // Necessary to define a new local here for the lambda to capture + + var fileLabel = new XNALinkLabel(WindowManager); + fileLabel.Name = nameof(fileLabel) + i.ToString(CultureInfo.InvariantCulture); + fileLabel.X = Constants.UIEmptySideSpace; + fileLabel.Y = y; + fileLabel.Text = (i + 1).ToString(CultureInfo.InvariantCulture) + ") " + string.Join(Environment.NewLine, Renderer.GetFixedTextLines(path, fileLabel.FontIndex, Width - fileLabel.X - Constants.UIEmptySideSpace)); + fileLabel.Tag = entries[i]; + fileLabel.LeftClick += (s, e) => FileSelected?.Invoke(this, new FileSelectedEventArgs(path)); + AddChild(fileLabel); + + y += fileLabel.Height + (Constants.UIVerticalSpacing * 2); + + fileLabels.Add(fileLabel); + } + + base.Initialize(); + } + + public override void Kill() + { + BackgroundTexture?.Dispose(); + base.Kill(); + } + } +} diff --git a/src/TSMapEditor/UI/SettingsPanel.cs b/src/TSMapEditor/UI/SettingsPanel.cs index 49ab973e..d5e087e7 100644 --- a/src/TSMapEditor/UI/SettingsPanel.cs +++ b/src/TSMapEditor/UI/SettingsPanel.cs @@ -71,6 +71,7 @@ public class SettingsPanel : EditorPanel { public SettingsPanel(WindowManager windowManager) : base(windowManager) { + BackgroundTexture = AssetLoader.CreateTexture(UISettings.ActiveSettings.BackgroundColor, 2, 2); } private XNADropDown ddRenderScale; @@ -81,6 +82,12 @@ public SettingsPanel(WindowManager windowManager) : base(windowManager) private XNACheckBox chkGraphicsLevel; private EditorTextBox tbTextEditorPath; + public override void Kill() + { + BackgroundTexture?.Dispose(); + base.Kill(); + } + public override void Initialize() { Width = 230; diff --git a/src/TSMapEditor/UI/TopBar/TopBarMenu.cs b/src/TSMapEditor/UI/TopBar/TopBarMenu.cs index f05fa9d5..ceaea537 100644 --- a/src/TSMapEditor/UI/TopBar/TopBarMenu.cs +++ b/src/TSMapEditor/UI/TopBar/TopBarMenu.cs @@ -480,6 +480,7 @@ private void SaveAs() if (UserSettings.Instance.LastScenarioPath.GetValue() != saveFileDialog.FileName) { + UserSettings.Instance.RecentFiles.PutEntry(saveFileDialog.FileName); UserSettings.Instance.LastScenarioPath.UserDefinedValue = saveFileDialog.FileName; _ = UserSettings.Instance.SaveSettingsAsync(); } diff --git a/src/TSMapEditor/UI/UIManager.cs b/src/TSMapEditor/UI/UIManager.cs index c7e123fd..354ef7eb 100644 --- a/src/TSMapEditor/UI/UIManager.cs +++ b/src/TSMapEditor/UI/UIManager.cs @@ -457,6 +457,7 @@ private void LoadMap() if (!createNew) { UserSettings.Instance.LastScenarioPath.UserDefinedValue = loadMapFilePath; + UserSettings.Instance.RecentFiles.PutEntry(loadMapFilePath); _ = UserSettings.Instance.SaveSettingsAsync(); } diff --git a/src/TSMapEditor/UI/Windows/SaveMapAsWindow.cs b/src/TSMapEditor/UI/Windows/SaveMapAsWindow.cs index afebd989..e94f10e1 100644 --- a/src/TSMapEditor/UI/Windows/SaveMapAsWindow.cs +++ b/src/TSMapEditor/UI/Windows/SaveMapAsWindow.cs @@ -110,6 +110,7 @@ private void BtnSave_LeftClick(object sender, EventArgs e) if (UserSettings.Instance.LastScenarioPath != path) { UserSettings.Instance.LastScenarioPath.UserDefinedValue = path; + UserSettings.Instance.RecentFiles.PutEntry(path); _ = UserSettings.Instance.SaveSettingsAsync(); }