CnC_Remastered_Collection

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

NavigationWidget.cs (5539B)


      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.Interface;
     17 using MobiusEditor.Model;
     18 using System;
     19 using System.Drawing;
     20 using System.Windows.Forms;
     21 
     22 namespace MobiusEditor.Widgets
     23 {
     24     public class MouseCellChangedEventArgs : EventArgs
     25     {
     26         public Point OldCell { get; private set; }
     27 
     28         public Point NewCell { get; private set; }
     29 
     30         public MouseCellChangedEventArgs(Point oldCell, Point newCell)
     31         {
     32             OldCell = oldCell;
     33             NewCell = newCell;
     34         }
     35     }
     36 
     37     public class NavigationWidget : IWidget
     38     {
     39         private static readonly Pen defaultMouseoverPen = new Pen(Color.Yellow, 4);
     40 
     41         private readonly MapPanel mapPanel;
     42         private readonly Size cellSize;
     43 
     44         private bool dragging = false;
     45         private Point lastMouseLocation;
     46 
     47         public CellMetrics Metrics { get; private set; }
     48 
     49         public Point MouseCell { get; private set; }
     50         public Point MouseSubPixel { get; private set; }
     51 
     52         private Size mouseoverSize = new Size(1, 1);
     53         public Size MouseoverSize
     54         {
     55             get => mouseoverSize;
     56             set => mouseoverSize = !value.IsEmpty ? new Size(value.Width | 1, value.Height | 1) : Size.Empty;
     57         }
     58 
     59         public event EventHandler<MouseCellChangedEventArgs> MouseCellChanged;
     60 
     61         public NavigationWidget(MapPanel mapPanel, CellMetrics metrics, Size cellSize)
     62         {
     63             this.mapPanel = mapPanel;
     64             this.mapPanel.MouseDown += MapPanel_MouseDown;
     65             this.mapPanel.MouseMove += MapPanel_MouseMove;
     66             Metrics = metrics;
     67             this.cellSize = cellSize;
     68         }
     69 
     70         public void Refresh()
     71         {
     72             OnMouseMove(mapPanel.PointToClient(Control.MousePosition));
     73         }
     74 
     75         private void MapPanel_MouseDown(object sender, MouseEventArgs e)
     76         {
     77             if ((e.Button & MouseButtons.Middle) != MouseButtons.None)
     78             {
     79                 lastMouseLocation = e.Location;
     80                 dragging = true;
     81             }
     82         }
     83 
     84         private void MapPanel_MouseMove(object sender, MouseEventArgs e)
     85         {
     86             OnMouseMove(e.Location);
     87         }
     88 
     89         private void OnMouseMove(Point location)
     90         {
     91             if (dragging)
     92             {
     93                 if ((Control.MouseButtons & MouseButtons.Middle) == MouseButtons.None)
     94                 {
     95                     dragging = false;
     96                 }
     97                 else
     98                 {
     99                     var delta = location - (Size)lastMouseLocation;
    100                     if (!delta.IsEmpty)
    101                     {
    102                         mapPanel.AutoScrollPosition = new Point(-mapPanel.AutoScrollPosition.X - delta.X, -mapPanel.AutoScrollPosition.Y - delta.Y);
    103                     }
    104                 }
    105             }
    106 
    107             lastMouseLocation = location;
    108 
    109             var newMousePosition = mapPanel.ClientToMap(location);
    110             MouseSubPixel = new Point(
    111                 (newMousePosition.X * Globals.PixelWidth / cellSize.Width) % Globals.PixelWidth,
    112                 (newMousePosition.Y * Globals.PixelHeight / cellSize.Height) % Globals.PixelHeight
    113             );
    114 
    115             var newMouseCell = new Point(newMousePosition.X / cellSize.Width, newMousePosition.Y / cellSize.Height);
    116             if (MouseCell == newMouseCell)
    117             {
    118                 return;
    119             }
    120 
    121             if (!Metrics.Contains(newMouseCell))
    122             {
    123                 return;
    124             }
    125 
    126             var oldCell = MouseCell;
    127             MouseCell = newMouseCell;
    128 
    129             MouseCellChanged?.Invoke(this, new MouseCellChangedEventArgs(oldCell, MouseCell));
    130 
    131             mapPanel.Invalidate();
    132         }
    133 
    134         public void Render(Graphics graphics)
    135         {
    136             if (!MouseoverSize.IsEmpty)
    137             {
    138                 var rect = new Rectangle(new Point(MouseCell.X * cellSize.Width, MouseCell.Y * cellSize.Height), cellSize);
    139                 rect.Inflate(cellSize.Width * (MouseoverSize.Width / 2), cellSize.Height * (MouseoverSize.Height / 2));
    140                 graphics.DrawRectangle(defaultMouseoverPen, rect);
    141             }
    142         }
    143 
    144         #region IDisposable Support
    145         private bool disposedValue = false;
    146 
    147         protected virtual void Dispose(bool disposing)
    148         {
    149             if (!disposedValue)
    150             {
    151                 if (disposing)
    152                 {
    153                     mapPanel.MouseDown -= MapPanel_MouseDown;
    154                     mapPanel.MouseMove -= MapPanel_MouseMove;
    155                 }
    156                 disposedValue = true;
    157             }
    158         }
    159 
    160         public void Dispose()
    161         {
    162             Dispose(true);
    163         }
    164         #endregion
    165     }
    166 }