Mesen-SX/UI/Debugger/PpuViewer/ctrlImagePanel.cs

152 lines
5 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Mesen.GUI.Controls;
using Mesen.GUI.Forms;
using System.Drawing.Imaging;
namespace Mesen.GUI.Debugger.PpuViewer
{
public partial class ctrlImagePanel : BaseControl
{
private int _scale = 1;
private Size _imageSize;
private bool _mouseDown = false;
private bool _dragging = false;
private Point _lastLocation = Point.Empty;
public Rectangle Selection { get { return ctrlImageViewer.Selection; } set { ctrlImageViewer.Selection = value; } }
public Rectangle Overlay { get { return ctrlImageViewer.Overlay; } set { ctrlImageViewer.Overlay = value; } }
public int SelectionWrapPosition { get { return ctrlImageViewer.SelectionWrapPosition; } set { ctrlImageViewer.SelectionWrapPosition = value; } }
public Size ImageSize { get { return _imageSize; } set { _imageSize = value; UpdateMapSize(); } }
public Image Image { get { return ctrlImageViewer.Image; } set { ctrlImageViewer.Image = value; } }
public int ImageScale { get { return _scale; } set { _scale = value; UpdateMapSize(); } }
public int GridSizeX { get { return ctrlImageViewer.GridSizeX; } set { ctrlImageViewer.GridSizeX = value; } }
public int GridSizeY { get { return ctrlImageViewer.GridSizeY; } set { ctrlImageViewer.GridSizeY = value; } }
public Point ScrollOffsets { get { return new Point(ctrlPanel.HorizontalScroll.Value, ctrlPanel.VerticalScroll.Value); } }
public new event EventHandler MouseLeave { add { ctrlImageViewer.MouseLeave += value; } remove { ctrlImageViewer.MouseLeave -= value; } }
public new event MouseEventHandler MouseMove { add { ctrlImageViewer.MouseMove += value; } remove { ctrlImageViewer.MouseMove -= value; } }
public new event MouseEventHandler MouseClick;
public ctrlImagePanel()
{
InitializeComponent();
if(DesignMode) {
return;
}
ctrlPanel.OnZoom += (scaleDelta) => {
double hori = (double)ctrlPanel.HorizontalScroll.Value / _scale + (double)ctrlPanel.Width / 2 / _scale;
double vert = (double)ctrlPanel.VerticalScroll.Value / _scale + (double)ctrlPanel.Height / 2 / _scale;
_scale = Math.Min(16, Math.Max(1, _scale + scaleDelta));
UpdateMapSize();
int horizontalScroll = Math.Max(0, Math.Min((int)(hori * _scale) - ctrlPanel.Width / 2, ctrlPanel.HorizontalScroll.Maximum));
int verticalScroll = Math.Max(0, Math.Min((int)(vert * _scale) - ctrlPanel.Height / 2, ctrlPanel.VerticalScroll.Maximum));
//Set the values twice to avoid a scroll position bug
ctrlPanel.HorizontalScroll.Value = horizontalScroll;
ctrlPanel.HorizontalScroll.Value = horizontalScroll;
ctrlPanel.VerticalScroll.Value = verticalScroll;
ctrlPanel.VerticalScroll.Value = verticalScroll;
};
ctrlImageViewer.MouseDown += (s, e) => {
if(e.Button == MouseButtons.Left) {
_mouseDown = true;
_lastLocation = e.Location;
}
};
ctrlImageViewer.MouseUp += (s, e) => {
_mouseDown = false;
_dragging = false;
};
ctrlImageViewer.MouseClick += (s, e) => {
if(!_dragging) {
this.MouseClick?.Invoke(s, e);
}
};
ctrlImageViewer.MouseMove += ctrlImageViewer_MouseMove;
}
private void ctrlImageViewer_MouseMove(object sender, MouseEventArgs e)
{
if(_mouseDown) {
_dragging = true;
ctrlImageViewer.MouseMove -= ctrlImageViewer_MouseMove;
int hScroll = Math.Min(ctrlPanel.HorizontalScroll.Maximum, Math.Max(0, ctrlPanel.HorizontalScroll.Value - (e.Location.X - _lastLocation.X)));
int vScroll = Math.Min(ctrlPanel.VerticalScroll.Maximum, Math.Max(0, ctrlPanel.VerticalScroll.Value - (e.Location.Y - _lastLocation.Y)));
ctrlPanel.HorizontalScroll.Value = hScroll;
ctrlPanel.HorizontalScroll.Value = hScroll;
ctrlPanel.VerticalScroll.Value = vScroll;
ctrlPanel.VerticalScroll.Value = vScroll;
ctrlImageViewer.MouseMove += ctrlImageViewer_MouseMove;
}
}
private void UpdateMapSize()
{
ctrlImageViewer.Width = ImageSize.Width * _scale;
ctrlImageViewer.Height = ImageSize.Height * _scale;
ctrlImageViewer.ImageScale = _scale;
ctrlImageViewer.Invalidate();
}
protected override void OnInvalidated(InvalidateEventArgs e)
{
base.OnInvalidated(e);
ctrlImageViewer.Invalidate();
}
public void ZoomIn()
{
_scale = Math.Min(16, _scale + 1);
UpdateMapSize();
}
public void ZoomOut()
{
_scale = Math.Max(1, _scale - 1);
UpdateMapSize();
}
public void ScrollTo(int scrollPos)
{
ctrlPanel.VerticalScroll.Value = scrollPos;
ctrlPanel.VerticalScroll.Value = scrollPos;
ctrlPanel.HorizontalScroll.Value = 0;
ctrlPanel.HorizontalScroll.Value = 0;
}
public void CopyToClipboard()
{
Clipboard.SetImage(this.Image);
}
public void SaveAsPng()
{
using(SaveFileDialog sfd = new SaveFileDialog()) {
sfd.SetFilter("PNG files|*.png");
if(sfd.ShowDialog() == DialogResult.OK) {
this.Image.Save(sfd.FileName, ImageFormat.Png);
}
}
}
}
}