CnC_Remastered_Collection

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

WaypointsTool.cs (7510B)


      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;
     22 using System.Drawing;
     23 using System.Linq;
     24 using System.Windows.Forms;
     25 
     26 namespace MobiusEditor.Tools
     27 {
     28     public class WaypointsTool : ViewTool
     29     {
     30         private readonly ComboBox waypointCombo;
     31 
     32         private (Waypoint waypoint, int? cell)? undoWaypoint;
     33         private (Waypoint waypoint, int? cell)? redoWaypoint;
     34 
     35         private bool placementMode;
     36 
     37         public WaypointsTool(MapPanel mapPanel, MapLayerFlag layers, ToolStripStatusLabel statusLbl, ComboBox waypointCombo, IGamePlugin plugin, UndoRedoList<UndoRedoEventArgs> url)
     38             : base(mapPanel, layers, statusLbl, plugin, url)
     39         {
     40             this.mapPanel.MouseDown += MapPanel_MouseDown;
     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.waypointCombo = waypointCombo;
     46 
     47             UpdateStatus();
     48         }
     49 
     50         private void MapPanel_MouseDown(object sender, MouseEventArgs e)
     51         {
     52             if (placementMode)
     53             {
     54                 if (e.Button == MouseButtons.Left)
     55                 {
     56                     SetWaypoint(navigationWidget.MouseCell);
     57                 }
     58                 else if (e.Button == MouseButtons.Right)
     59                 {
     60                     RemoveWaypoint(navigationWidget.MouseCell);
     61                 }
     62             }
     63             else if ((e.Button == MouseButtons.Left) || (e.Button == MouseButtons.Right))
     64             {
     65                 PickWaypoint(navigationWidget.MouseCell);
     66             }
     67         }
     68 
     69         private void WaypointsTool_KeyDown(object sender, KeyEventArgs e)
     70         {
     71             if (e.KeyCode == Keys.ShiftKey)
     72             {
     73                 EnterPlacementMode();
     74             }
     75         }
     76 
     77         private void WaypointsTool_KeyUp(object sender, KeyEventArgs e)
     78         {
     79             if (e.KeyCode == Keys.ShiftKey)
     80             {
     81                 ExitPlacementMode();
     82             }
     83         }
     84 
     85         private void MapPanel_MouseMove(object sender, MouseEventArgs e)
     86         {
     87             if (!placementMode && (Control.ModifierKeys == Keys.Shift))
     88             {
     89                 EnterPlacementMode();
     90             }
     91             else if (placementMode && (Control.ModifierKeys == Keys.None))
     92             {
     93                 ExitPlacementMode();
     94             }
     95         }
     96 
     97         private void SetWaypoint(Point location)
     98         {
     99             if (map.Metrics.GetCell(location, out int cell))
    100             {
    101                 var waypoint = map.Waypoints[waypointCombo.SelectedIndex];
    102                 if (waypoint.Cell != cell)
    103                 {
    104                     if (undoWaypoint == null)
    105                     {
    106                         undoWaypoint = (waypoint, waypoint.Cell);
    107                     }
    108                     else if (undoWaypoint.Value.cell == cell)
    109                     {
    110                         undoWaypoint = null;
    111                     }
    112 
    113                     waypoint.Cell = cell;
    114                     redoWaypoint = (waypoint, waypoint.Cell);
    115 
    116                     CommitChange();
    117 
    118                     mapPanel.Invalidate();
    119 
    120                     plugin.Dirty = true;
    121                 }
    122             }
    123         }
    124 
    125         private void RemoveWaypoint(Point location)
    126         {
    127             if (map.Metrics.GetCell(location, out int cell))
    128             {
    129                 var waypoint = map.Waypoints.Where(w => w.Cell == cell).FirstOrDefault();
    130                 if (waypoint != null)
    131                 {
    132                     if (undoWaypoint == null)
    133                     {
    134                         undoWaypoint = (waypoint, waypoint.Cell);
    135                     }
    136 
    137                     waypoint.Cell = null;
    138                     redoWaypoint = (waypoint, null);
    139 
    140                     CommitChange();
    141 
    142                     mapPanel.Invalidate();
    143 
    144                     plugin.Dirty = true;
    145                 }
    146             }
    147         }
    148 
    149         private void EnterPlacementMode()
    150         {
    151             if (placementMode)
    152             {
    153                 return;
    154             }
    155 
    156             placementMode = true;
    157 
    158             UpdateStatus();
    159         }
    160 
    161         private void ExitPlacementMode()
    162         {
    163             if (!placementMode)
    164             {
    165                 return;
    166             }
    167 
    168             placementMode = false;
    169 
    170             UpdateStatus();
    171         }
    172 
    173         private void PickWaypoint(Point location)
    174         {
    175             if (map.Metrics.GetCell(location, out int cell))
    176             {
    177                 for (var i = 0; i < map.Waypoints.Length; ++i)
    178                 {
    179                     if (map.Waypoints[i].Cell == cell)
    180                     {
    181                         waypointCombo.SelectedIndex = i;
    182                         break;
    183                     }
    184                 }
    185             }
    186         }
    187 
    188         private void CommitChange()
    189         {
    190             var undoWaypoint2 = undoWaypoint;
    191             void undoAction(UndoRedoEventArgs e)
    192             {
    193                 undoWaypoint2.Value.waypoint.Cell = undoWaypoint2.Value.cell;
    194                 mapPanel.Invalidate();
    195             }
    196 
    197             var redoWaypoint2 = redoWaypoint;
    198             void redoAction(UndoRedoEventArgs e)
    199             {
    200                 redoWaypoint2.Value.waypoint.Cell = redoWaypoint2.Value.cell;
    201                 mapPanel.Invalidate();
    202             }
    203 
    204             undoWaypoint = null;
    205             redoWaypoint = null;
    206 
    207             url.Track(undoAction, redoAction);
    208         }
    209 
    210         private void UpdateStatus()
    211         {
    212             if (placementMode)
    213             {
    214                 statusLbl.Text = "Left-Click to set cell waypoint, Right-Click to clear cell waypoint";
    215             }
    216             else
    217             {
    218                 statusLbl.Text = "Shift to enter placement mode, Left-Click or Right-Click to pick cell waypoint";
    219             }
    220         }
    221 
    222         #region IDisposable Support
    223         private bool disposedValue = false;
    224 
    225         protected override void Dispose(bool disposing)
    226         {
    227             if (!disposedValue)
    228             {
    229                 if (disposing)
    230                 {
    231                     mapPanel.MouseDown -= MapPanel_MouseDown;
    232                     mapPanel.MouseMove -= MapPanel_MouseMove;
    233                     (mapPanel as Control).KeyDown -= WaypointsTool_KeyDown;
    234                     (mapPanel as Control).KeyUp -= WaypointsTool_KeyUp;
    235                 }
    236                 disposedValue = true;
    237             }
    238 
    239             base.Dispose(disposing);
    240         }
    241         #endregion
    242     }
    243 }