diff --git a/OpenRA.Editor/Form1.Designer.cs b/OpenRA.Editor/Form1.Designer.cs index aef0537b3b..fc366f0302 100644 --- a/OpenRA.Editor/Form1.Designer.cs +++ b/OpenRA.Editor/Form1.Designer.cs @@ -39,7 +39,6 @@ this.actorPalette = new System.Windows.Forms.FlowLayoutPanel(); this.tabPage3 = new System.Windows.Forms.TabPage(); this.resourcePalette = new System.Windows.Forms.FlowLayoutPanel(); - this.surface1 = new OpenRA.Editor.Surface(); this.menuStrip1 = new System.Windows.Forms.MenuStrip(); this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.newToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -60,6 +59,7 @@ this.spawnpointsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.tt = new System.Windows.Forms.ToolTip(this.components); this.folderBrowser = new System.Windows.Forms.FolderBrowserDialog(); + this.surface1 = new OpenRA.Editor.Surface(); this.toolStripContainer1.ContentPanel.SuspendLayout(); this.toolStripContainer1.TopToolStripPanel.SuspendLayout(); this.toolStripContainer1.SuspendLayout(); @@ -183,16 +183,6 @@ this.resourcePalette.Size = new System.Drawing.Size(190, 655); this.resourcePalette.TabIndex = 3; // - // surface1 - // - this.surface1.BackColor = System.Drawing.Color.Black; - this.surface1.Dock = System.Windows.Forms.DockStyle.Fill; - this.surface1.Location = new System.Drawing.Point(0, 0); - this.surface1.Name = "surface1"; - this.surface1.Size = new System.Drawing.Size(783, 681); - this.surface1.TabIndex = 5; - this.surface1.Text = "surface1"; - // // menuStrip1 // this.menuStrip1.Dock = System.Windows.Forms.DockStyle.None; @@ -343,6 +333,16 @@ // this.tt.ShowAlways = true; // + // surface1 + // + this.surface1.BackColor = System.Drawing.Color.Black; + this.surface1.Dock = System.Windows.Forms.DockStyle.Fill; + this.surface1.Location = new System.Drawing.Point(0, 0); + this.surface1.Name = "surface1"; + this.surface1.Size = new System.Drawing.Size(783, 681); + this.surface1.TabIndex = 5; + this.surface1.Text = "surface1"; + // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -354,6 +354,7 @@ this.Name = "Form1"; this.Text = "OpenRA Editor"; this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyUp); + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.OnFormClosing); this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown); this.toolStripContainer1.ContentPanel.ResumeLayout(false); this.toolStripContainer1.TopToolStripPanel.ResumeLayout(false); diff --git a/OpenRA.Editor/Form1.cs b/OpenRA.Editor/Form1.cs index a2b24f5d61..236ae6277b 100644 --- a/OpenRA.Editor/Form1.cs +++ b/OpenRA.Editor/Form1.cs @@ -43,11 +43,16 @@ namespace OpenRA.Editor folderBrowser.SelectedPath = new string[] { Environment.CurrentDirectory, "mods", currentMod, "maps" } .Aggregate(Path.Combine); + + surface1.AfterChange += MakeDirty; } + void MakeDirty() { dirty = true; } + string loadedMapName; string currentMod = "ra"; TileSet tileset; + bool dirty = false; void LoadMap(string mapname) { @@ -68,6 +73,8 @@ namespace OpenRA.Editor var map = new Map(new Folder(mapname)); PrepareMapResources(manifest, map); + + dirty = false; } void NewMap(Map map) @@ -86,6 +93,8 @@ namespace OpenRA.Editor foreach (var pkg in manifest.Packages) FileSystem.Mount(pkg); PrepareMapResources(manifest, map); + + MakeDirty(); } void PrepareMapResources(Manifest manifest, Map map) @@ -328,6 +337,8 @@ namespace OpenRA.Editor surface1.Map.PlayerCount = surface1.Map.Waypoints.Count; surface1.Map.Package = new Folder(loadedMapName); surface1.Map.Save(loadedMapName); + + dirty = false; } } @@ -337,7 +348,6 @@ namespace OpenRA.Editor if (DialogResult.OK == folderBrowser.ShowDialog()) { - loadedMapName = folderBrowser.SelectedPath; SaveClicked(sender, e); } @@ -420,7 +430,21 @@ namespace OpenRA.Editor loadedMapName = null; /* editor needs to think this hasnt been saved */ Directory.Delete(savePath, true); + MakeDirty(); } } + + void OnFormClosing(object sender, FormClosingEventArgs e) + { + if (!dirty) return; + + switch (MessageBox.Show("The map has been modified since it was last saved. Save changes now?", + "Unsaved Changes", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Exclamation)) + { + case DialogResult.Yes: SaveClicked(null, EventArgs.Empty); break; + case DialogResult.No: break; + case DialogResult.Cancel: e.Cancel = true; break; + } + } } } \ No newline at end of file diff --git a/OpenRA.Editor/Form1.resx b/OpenRA.Editor/Form1.resx index a6beb3464c..1b4bd4ba55 100644 --- a/OpenRA.Editor/Form1.resx +++ b/OpenRA.Editor/Form1.resx @@ -138,7 +138,7 @@ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6 - JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsQAAALEAGtI711AAACeklE + JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsMAAALDAE/QCLIAAACeklE QVQ4T6WTWUiUURiG/4suurJIjUIwskQsEANDqosQpUVNKbdCSRPKrQVDMddmXEedGdcpFXNGnUYdrSzF sEIoFInQcqHE1CwoKsXUUMnt6Z+RLMtA8OK5OZz3Oe/5OEcAhPWwpnBaodZZmqfjWmY5GSo98XJNwq9D 1yQIilLhFaYIMIQuxZaZJ4uy6FS1T2BUIUKdNsdPhL9pqpEp/ne18PiiE94RCjzDco0C+rs1zIzXGvkx @@ -155,7 +155,7 @@ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6 - JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsQAAALEAGtI711AAACMklE + JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsMAAALDAE/QCLIAAACMklE QVQ4T6WT3UuTcRTH9y90303QRbc1NYZrMRs86hzKsmFoIb09kqZpunxJUqxMxZYvkK1w6sTlahJOKvIF TJEUMZaSlZkrWuJQU3QiGHz7nZ+wn0vrQh84Nw98Puc553wfBQDFXorDL18EQOXuXEGHaxlPHItoafbj kXUW9XU/YLnnxd3yaZSWfEZR4Qfk5Y7japaHoVBwAYF9vUBd7Tq9/Oeztr4BfVIfTic95xUUuJ4tcUFl @@ -215,7 +215,7 @@ XTesb3QPLh88M+QwdP6m681Lt7xuXbu94vbgcOjwnZHokdE77DtTd1PuvriXeW/h/sYH6AdFD6UeVjxS fNTws+7PbaOWo6fHXMf6Hwc/vj/OGn/2S8Yv7ycKnpCfVEyqTDZPmU2dmnafvvF05dOJZ+nPFmYKf5X+ tfa5zvMffnP8rX82YnbiBf/Fp99LXsq/PPRq2aueuYC5R69TXy/MF72Rf3P4LeNt37vwd5MLWe+x7ys/ - 6H7o/ujz8cGn1E+f/gUDmPP8usTo0wAAAAlwSFlzAAALEAAACxABrSO9dQAAAN5JREFUOE+FUwEOAyEI + 6H7o/ujz8cGn1E+f/gUDmPP8usTo0wAAAAlwSFlzAAALDAAACwwBP0AiyAAAAN5JREFUOE+FUwEOAyEI 8+k+7X7GoFBWmZdtISYgtS3csrXsFtvzf2Mv8/8d4Hkec2SLM+IHzJsjdwVAcxQrtl8OsDgBxPMGgKJG SQkwMlI2zSCS+cuL0YCceHEDAcBbM6gTQOhDDpnBxHqVOsmgdYvmfCxk7q+JpDZN4yQOJhOAOtmslGna MYE3AN2HeBEmyvhYZ44mL5rRXkijgoAZAA3nCVBzbzM5vuE8x8xmbGIzqE1LkNwHOO2RZmZOjQYTjoWF @@ -225,7 +225,7 @@ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6 - JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsQAAALEAGtI711AAACR0lE + JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsMAAALDAE/QCLIAAACR0lE QVQ4T6WTXUiTARSGdxkRRBdB0IUREV1EKRFEYYuQAklL8sKQfphUoJSUWJbLxAVZWqyBio5WajorM1PL xExUlLQfbU5n0lygRerMP/qxOZ92vpjfCKLAi3P5Puc957xHA2gWUoo49147gWUqbSPrdjOXChrQm56S lFVFvKEcXaqV2OQiohMt7Esw+6Ro5gGeWfhbff0BY9NzDI3N0f/JS6fLy7rd6f8HcNsdOI6EYD8cjK3V @@ -242,7 +242,7 @@ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6 - JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsQAAALEAGtI711AAACCklE + JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsMAAALDAE/QCLIAAACCklE QVQ4T6WT30tTUQDHz39QD0UQSpAPIkgPyR60AiUiyoGBL4qZjOyt0tZP9tBDk1AsXIhj93ILdd27DPPH 3VwrUrdK2ioJHAgVOdoPaQsarBg43L6ec+akuRsEPnw5D4fP5/vlXg4BQHaSf8LjjwdqaTA2cg+y1Ith qxmi5Tas/SYWk+QRoPgmtNsLcPq7GYX8+XoTqaUL+KR2cAmDxeBgqeBv2NhWzwUFOBk4g5/zRxB3V8Es @@ -257,7 +257,7 @@ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6 - JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsQAAALEAGtI711AAADLklE + JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsMAAALDAE/QCLIAAADLklE QVQ4T3WS60/ScRjFf39CL3rR1ovurduWbbU2t7ZqdlkXt7Lrym6O1VoXcdYqQ54wKlGxABE1CzWF0nIm lZcoTbyUNJFIzDJSJK+E0qy8wInvz+i2erazfd+cz3m+zw4nTS+FLOeZNim3Vp6UU5sqvf5MSZqnyjhV pfKUvEx54kqp8rCkWHVQVKSJPHtbs+tUgSYiOicVAMfEqfR1dVFCGSqrX94cHQeN/aXhbyD3Zz91uf3U @@ -277,7 +277,7 @@ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6 - JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsQAAALEAGtI711AAABrUlE + JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsMAAALDAE/QCLIAAABrUlE QVQ4T6WTWyhDcRzHl8g1D/IkxZ4mjcgDB0U5ubbVbJLkkubJSt7w6M1eENHUENrktmzJ3HKEiSh7US5l QiK5JUXpy/9f/9O2zhY59at//c/n87uc35EBkP0nAsL6Bi33E9CpeBINJElHthIkvBNKChh8YVPi1Cpn Eo7ANSnJwQUMfnLEobVejZbaCnis8VRiyFSgXJ4QWOAPO5fXYJ2xo1HD48QcRSV5CfHSAn94fV0gL9Jn diff --git a/OpenRA.Editor/Surface.cs b/OpenRA.Editor/Surface.cs index 9244917fb4..dd6541b79a 100644 --- a/OpenRA.Editor/Surface.cs +++ b/OpenRA.Editor/Surface.cs @@ -33,6 +33,7 @@ namespace OpenRA.Editor WaypointTemplate Waypoint; public bool IsPanning; + public event Action AfterChange = () => { }; Dictionary ActorTemplates = new Dictionary(); Dictionary ResourceTemplates = new Dictionary(); @@ -131,6 +132,8 @@ namespace OpenRA.Editor /* todo: optimize */ foreach (var ch in Chunks.Values) ch.Dispose(); Chunks.Clear(); + + AfterChange(); } int2 FindEdge(int2 p, int2 d, TileReference replace) @@ -180,6 +183,8 @@ namespace OpenRA.Editor } } } + + AfterChange(); } int wpid; @@ -199,6 +204,8 @@ namespace OpenRA.Editor if (k.Key != null) Map.Waypoints.Remove(k.Key); Map.Waypoints.Add(NextWpid(), GetBrushLocation()); + + AfterChange(); } void Erase() @@ -224,6 +231,8 @@ namespace OpenRA.Editor var k = Map.Waypoints.FirstOrDefault(a => a.Value == GetBrushLocation()); if (k.Key != null) Map.Waypoints.Remove(k.Key); + + AfterChange(); } void Draw() @@ -232,6 +241,8 @@ namespace OpenRA.Editor if (Actor != null) DrawWithActor(); if (Resource != null) DrawWithResource(); if (Waypoint != null) DrawWithWaypoint(); + + AfterChange(); } int id; @@ -252,6 +263,8 @@ namespace OpenRA.Editor var owner = "Neutral"; var id = NextActorName(); Map.Actors[id] = new ActorReference(id,Actor.Info.Name.ToLowerInvariant(), GetBrushLocation(), owner); + + AfterChange(); } System.Random r = new System.Random(); @@ -271,6 +284,8 @@ namespace OpenRA.Editor Chunks[ch].Dispose(); Chunks.Remove(ch); } + + AfterChange(); } protected override void OnMouseDown(MouseEventArgs e)