CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

CellTriggersTool.cs (8640B)


      1 //
      2 // Copyright 2020 Electronic Arts Inc.
      3 //
      4 // The Command & Conquer Map Editor and corresponding source code is free 
      5 // software: you can redistribute it and/or modify it under the terms of 
      6 // the GNU General Public License as published by the Free Software Foundation, 
      7 // either version 3 of the License, or (at your option) any later version.
      8 
      9 // The Command & Conquer Map Editor and corresponding source code is distributed 
     10 // in the hope that it will be useful, but with permitted additional restrictions 
     11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 
     12 // distributed with this program. You should have received a copy of the 
     13 // GNU General Public License along with permitted additional restrictions 
     14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
     15 using MobiusEditor.Controls;
     16 using MobiusEditor.Event;
     17 using MobiusEditor.Interface;
     18 using MobiusEditor.Model;
     19 using MobiusEditor.Utility;
     20 using MobiusEditor.Widgets;
     21 using System.Collections.Generic;
     22 using System.Drawing;
     23 using System.Windows.Forms;
     24 
     25 namespace MobiusEditor.Tools
     26 {
     27     public class CellTriggersTool : ViewTool
     28     {
     29         private readonly ComboBox triggerCombo;
     30 
     31         private readonly Dictionary<int, CellTrigger> undoCellTriggers = new Dictionary<int, CellTrigger>();
     32         private readonly Dictionary<int, CellTrigger> redoCellTriggers = new Dictionary<int, CellTrigger>();
     33 
     34         private bool placementMode;
     35 
     36         public CellTriggersTool(MapPanel mapPanel, MapLayerFlag layers, ToolStripStatusLabel statusLbl, ComboBox triggerCombo, IGamePlugin plugin, UndoRedoList<UndoRedoEventArgs> url)
     37             : base(mapPanel, layers, statusLbl, plugin, url)
     38         {
     39             this.mapPanel.MouseDown += MapPanel_MouseDown;
     40             this.mapPanel.MouseUp += MapPanel_MouseUp;
     41             this.mapPanel.MouseMove += MapPanel_MouseMove;
     42             (this.mapPanel as Control).KeyDown += WaypointsTool_KeyDown;
     43             (this.mapPanel as Control).KeyUp += WaypointsTool_KeyUp;
     44 
     45             this.triggerCombo = triggerCombo;
     46 
     47             navigationWidget.MouseCellChanged += MouseoverWidget_MouseCellChanged;
     48 
     49             UpdateStatus();
     50         }
     51 
     52         private void MapPanel_MouseDown(object sender, MouseEventArgs e)
     53         {
     54             if (placementMode)
     55             {
     56                 if (e.Button == MouseButtons.Left)
     57                 {
     58                     SetCellTrigger(navigationWidget.MouseCell);
     59                 }
     60                 else if (e.Button == MouseButtons.Right)
     61                 {
     62                     RemoveCellTrigger(navigationWidget.MouseCell);
     63                 }
     64             }
     65             else if ((e.Button == MouseButtons.Left) || (e.Button == MouseButtons.Right))
     66             {
     67                 PickCellTrigger(navigationWidget.MouseCell);
     68             }
     69         }
     70 
     71         private void MapPanel_MouseUp(object sender, MouseEventArgs e)
     72         {
     73             if ((undoCellTriggers.Count > 0) || (redoCellTriggers.Count > 0))
     74             {
     75                 CommitChange();
     76             }
     77         }
     78 
     79         private void WaypointsTool_KeyDown(object sender, KeyEventArgs e)
     80         {
     81             if (e.KeyCode == Keys.ShiftKey)
     82             {
     83                 EnterPlacementMode();
     84             }
     85         }
     86 
     87         private void WaypointsTool_KeyUp(object sender, KeyEventArgs e)
     88         {
     89             if (e.KeyCode == Keys.ShiftKey)
     90             {
     91                 ExitPlacementMode();
     92             }
     93         }
     94 
     95         private void MapPanel_MouseMove(object sender, MouseEventArgs e)
     96         {
     97             if (!placementMode && (Control.ModifierKeys == Keys.Shift))
     98             {
     99                 EnterPlacementMode();
    100             }
    101             else if (placementMode && (Control.ModifierKeys == Keys.None))
    102             {
    103                 ExitPlacementMode();
    104             }
    105 
    106             
    107         }
    108 
    109         private void MouseoverWidget_MouseCellChanged(object sender, MouseCellChangedEventArgs e)
    110         {
    111             if (placementMode)
    112             {
    113                 if (Control.MouseButtons == MouseButtons.Left)
    114                 {
    115                     SetCellTrigger(e.NewCell);
    116                 }
    117                 else if (Control.MouseButtons == MouseButtons.Right)
    118                 {
    119                     RemoveCellTrigger(e.NewCell);
    120                 }
    121             }
    122         }
    123 
    124         private void SetCellTrigger(Point location)
    125         {
    126             if (map.Metrics.GetCell(location, out int cell))
    127             {
    128                 if (map.CellTriggers[cell] == null)
    129                 {
    130                     if (!undoCellTriggers.ContainsKey(cell))
    131                     {
    132                         undoCellTriggers[cell] = map.CellTriggers[cell];
    133                     }
    134 
    135                     var cellTrigger = new CellTrigger { Trigger = triggerCombo.SelectedItem as string };
    136                     map.CellTriggers[cell] = cellTrigger;
    137                     redoCellTriggers[cell] = cellTrigger;
    138 
    139                     mapPanel.Invalidate();
    140 
    141                     plugin.Dirty = true;
    142                 }
    143             }
    144         }
    145 
    146         private void RemoveCellTrigger(Point location)
    147         {
    148             if (map.Metrics.GetCell(location, out int cell))
    149             {
    150                 var cellTrigger = map.CellTriggers[cell];
    151                 if (cellTrigger != null)
    152                 {
    153                     if (!undoCellTriggers.ContainsKey(cell))
    154                     {
    155                         undoCellTriggers[cell] = map.CellTriggers[cell];
    156                     }
    157 
    158                     map.CellTriggers[cell] = null;
    159                     redoCellTriggers[cell] = null;
    160 
    161                     mapPanel.Invalidate();
    162 
    163                     plugin.Dirty = true;
    164                 }
    165             }
    166         }
    167 
    168         private void EnterPlacementMode()
    169         {
    170             if (placementMode)
    171             {
    172                 return;
    173             }
    174 
    175             placementMode = true;
    176 
    177             UpdateStatus();
    178         }
    179 
    180         private void ExitPlacementMode()
    181         {
    182             if (!placementMode)
    183             {
    184                 return;
    185             }
    186 
    187             placementMode = false;
    188 
    189             UpdateStatus();
    190         }
    191 
    192         private void PickCellTrigger(Point location)
    193         {
    194             if (map.Metrics.GetCell(location, out int cell))
    195             {
    196                 var cellTrigger = map.CellTriggers[cell];
    197                 if (cellTrigger != null)
    198                 {
    199                     triggerCombo.SelectedItem = cellTrigger.Trigger;
    200                 }
    201             }
    202         }
    203 
    204         private void CommitChange()
    205         {
    206             var undoCellTriggers2 = new Dictionary<int, CellTrigger>(undoCellTriggers);
    207             void undoAction(UndoRedoEventArgs e)
    208             {
    209                 foreach (var kv in undoCellTriggers2)
    210                 {
    211                     e.Map.CellTriggers[kv.Key] = kv.Value;
    212                 }
    213                 e.MapPanel.Invalidate();
    214             }
    215 
    216             var redoCellTriggers2 = new Dictionary<int, CellTrigger>(redoCellTriggers);
    217             void redoAction(UndoRedoEventArgs e)
    218             {
    219                 foreach (var kv in redoCellTriggers2)
    220                 {
    221                     e.Map.CellTriggers[kv.Key] = kv.Value;
    222                 }
    223                 e.MapPanel.Invalidate();
    224             }
    225 
    226             undoCellTriggers.Clear();
    227             redoCellTriggers.Clear();
    228 
    229             url.Track(undoAction, redoAction);
    230         }
    231 
    232         private void UpdateStatus()
    233         {
    234             if (placementMode)
    235             {
    236                 statusLbl.Text = "Left-Click to set cell trigger, Right-Click to clear cell trigger";
    237             }
    238             else
    239             {
    240                 statusLbl.Text = "Shift to enter placement mode, Left-Click or Right-Click to pick cell trigger";
    241             }
    242         }
    243 
    244         #region IDisposable Support
    245         private bool disposedValue = false;
    246 
    247         protected override void Dispose(bool disposing)
    248         {
    249             if (!disposedValue)
    250             {
    251                 if (disposing)
    252                 {
    253                     mapPanel.MouseDown -= MapPanel_MouseDown;
    254                     mapPanel.MouseUp -= MapPanel_MouseUp;
    255                     mapPanel.MouseMove -= MapPanel_MouseMove;
    256                     (mapPanel as Control).KeyDown -= WaypointsTool_KeyDown;
    257                     (mapPanel as Control).KeyUp -= WaypointsTool_KeyUp;
    258 
    259                     navigationWidget.MouseCellChanged -= MouseoverWidget_MouseCellChanged;
    260                 }
    261                 disposedValue = true;
    262             }
    263 
    264             base.Dispose(disposing);
    265         }
    266         #endregion
    267     }
    268 }