Mesen-SX/UI/Emulation/DisplayManager.cs

265 lines
7.3 KiB
C#

using Mesen.GUI.Config;
using Mesen.GUI.Controls;
using Mesen.GUI.Forms;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Mesen.GUI.Emulation
{
public class DisplayManager
{
private frmMain _frm;
private ctrlRenderer _renderer;
private Panel _panel;
private MenuStrip _menu;
private ctrlRecentGames _recentGames;
private bool _resizeForm;
private bool _fullscreenMode;
private FormWindowState _originalWindowState;
private Size _originalWindowMinimumSize;
private frmFullscreenRenderer _frmFullscreenRenderer = null;
public bool Fullscreen { get { return _fullscreenMode; } }
public bool ExclusiveFullscreen { get { return _frmFullscreenRenderer != null; } }
public DisplayManager(frmMain frm, ctrlRenderer renderer, Panel panel, MenuStrip menu, ctrlRecentGames recentGames)
{
_frm = frm;
_renderer = renderer;
_panel = panel;
_menu = menu;
_recentGames = recentGames;
_renderer.MouseClick += ctrlRenderer_MouseClick;
_renderer.Enter += ctrlRenderer_Enter;
_renderer.MouseMove += ctrlRenderer_MouseMove;
_panel.MouseMove += ctrlRenderer_MouseMove;
_recentGames.MouseMove += ctrlRenderer_MouseMove;
_panel.Click += panelRenderer_Click;
_frm.Resize += frmMain_Resize;
_menu.VisibleChanged += menu_VisibleChanged;
}
private void frmMain_Resize(object sender, EventArgs e)
{
SetScaleBasedOnWindowSize();
}
private void menu_VisibleChanged(object sender, EventArgs e)
{
if(!_menu.Visible) {
_renderer.Top += _menu.Height;
} else {
_renderer.Top -= _menu.Height;
}
}
public bool HideMenuStrip
{
get { return (_fullscreenMode && !ConfigManager.Config.Video.UseExclusiveFullscreen) || ConfigManager.Config.Preferences.AutoHideMenu; }
}
private void ctrlRenderer_MouseMove(object sender, MouseEventArgs e)
{
if(sender != _recentGames) {
CursorManager.OnMouseMove((Control)sender);
}
if(this.HideMenuStrip && !_menu.ContainsFocus) {
if(sender == _renderer) {
_menu.Visible = _renderer.Top + e.Y < 30;
} else {
_menu.Visible = e.Y < 30;
}
}
}
private void ctrlRenderer_MouseClick(object sender, MouseEventArgs e)
{
if(this.HideMenuStrip) {
_menu.Visible = false;
}
CursorManager.CaptureMouse();
}
private void panelRenderer_Click(object sender, EventArgs e)
{
if(this.HideMenuStrip) {
_menu.Visible = false;
}
CursorManager.CaptureMouse();
_renderer.Focus();
}
private void ctrlRenderer_Enter(object sender, EventArgs e)
{
if(this.HideMenuStrip) {
_menu.Visible = false;
}
}
public void UpdateViewerSize()
{
if(_frmFullscreenRenderer != null) {
return;
}
if(HideMenuStrip) {
_menu.Visible = false;
}
ScreenSize screenSize = EmuApi.GetScreenSize(false);
if(_resizeForm && _frm.WindowState != FormWindowState.Maximized) {
_frm.Resize -= frmMain_Resize;
Size newSize = new Size(screenSize.Width, screenSize.Height);
_frm.ClientSize = new Size(newSize.Width, newSize.Height + (HideMenuStrip ? 0 : _panel.Top));
_frm.Resize += frmMain_Resize;
}
_renderer.Size = new Size(screenSize.Width, screenSize.Height);
_renderer.Top = (_panel.Height - _renderer.Height) / 2;
_renderer.Left = (_panel.Width - _renderer.Width) / 2;
}
public void SetScaleBasedOnDimensions(Size dimensions)
{
ScreenSize size = EmuApi.GetScreenSize(true);
double verticalScale = (double)dimensions.Height / size.Height;
double horizontalScale = (double)dimensions.Width / size.Width;
double scale = Math.Min(verticalScale, horizontalScale);
if(_fullscreenMode && ConfigManager.Config.Video.FullscreenForceIntegerScale) {
scale = Math.Floor(scale);
}
SetScale(scale, false);
}
public void SetScaleBasedOnWindowSize()
{
SetScaleBasedOnDimensions(_panel.ClientSize);
}
public void SetScale(double scale, bool resizeForm)
{
_resizeForm = resizeForm;
ConfigManager.Config.Video.VideoScale = scale;
ConfigManager.Config.Video.ApplyConfig();
ConfigManager.ApplyChanges();
UpdateViewerSize();
}
public void ToggleFullscreen()
{
SetFullscreenState(!_fullscreenMode);
}
public void SetFullscreenState(bool enabled)
{
if(_fullscreenMode == enabled) {
//Fullscreen mode already matches, no need to do anything
return;
}
bool saveState = !_fullscreenMode;
_fullscreenMode = enabled;
if(ConfigManager.Config.Video.UseExclusiveFullscreen) {
if(enabled && EmuRunner.IsRunning()) {
StartExclusiveFullscreenMode();
} else {
StopExclusiveFullscreenMode();
}
} else {
_frm.Resize -= frmMain_Resize;
if(enabled) {
StartFullscreenWindowMode(saveState);
} else {
StopFullscreenWindowMode();
}
_frm.Resize += frmMain_Resize;
UpdateViewerSize();
}
}
private void StartFullscreenWindowMode(bool saveState)
{
_menu.Visible = false;
if(saveState) {
_originalWindowState = _frm.WindowState;
_originalWindowMinimumSize = _frm.MinimumSize;
}
_frm.MinimumSize = new Size(0, 0);
_frm.WindowState = FormWindowState.Normal;
_frm.FormBorderStyle = FormBorderStyle.None;
_frm.WindowState = FormWindowState.Maximized;
SetScaleBasedOnWindowSize();
}
private void StopFullscreenWindowMode()
{
_menu.Visible = true;
_frm.WindowState = _originalWindowState;
_frm.MinimumSize = _originalWindowMinimumSize;
_frm.FormBorderStyle = FormBorderStyle.Sizable;
frmMain_Resize(null, EventArgs.Empty);
}
private void StopExclusiveFullscreenMode()
{
if(_frmFullscreenRenderer != null) {
_frmFullscreenRenderer.Close();
}
_fullscreenMode = false;
}
private Size GetFullscreenResolution()
{
if(ConfigManager.Config.Video.FullscreenResWidth > 0 && ConfigManager.Config.Video.FullscreenResHeight > 0) {
return new Size((int)ConfigManager.Config.Video.FullscreenResWidth, (int)ConfigManager.Config.Video.FullscreenResHeight);
}
return Screen.FromControl(_frm).Bounds.Size;
}
private void StartExclusiveFullscreenMode()
{
Size screenSize = GetFullscreenResolution();
Size originalWindowSize = _frm.Size;
double originalScale = ConfigManager.Config.Video.VideoScale;
_frm.Resize -= frmMain_Resize;
_frmFullscreenRenderer = new frmFullscreenRenderer();
_frmFullscreenRenderer.Shown += (object sender, EventArgs e) => {
_renderer.Visible = false;
SetScaleBasedOnDimensions(screenSize);
EmuApi.SetFullscreenMode(true, _frmFullscreenRenderer.Handle, (UInt32)screenSize.Width, (UInt32)screenSize.Height);
};
_frmFullscreenRenderer.FormClosing += (object sender, FormClosingEventArgs e) => {
EmuApi.SetFullscreenMode(false, _renderer.Handle, (UInt32)screenSize.Width, (UInt32)screenSize.Height);
_frm.Resize += frmMain_Resize;
_frmFullscreenRenderer = null;
_renderer.Visible = true;
_fullscreenMode = false;
frmMain_Resize(null, EventArgs.Empty);
SetScale(originalScale, false);
_frm.Size = originalWindowSize;
};
Screen currentScreen = Screen.FromHandle(_frm.Handle);
_frmFullscreenRenderer.StartPosition = FormStartPosition.Manual;
_frmFullscreenRenderer.Top = currentScreen.Bounds.Top;
_frmFullscreenRenderer.Left = currentScreen.Bounds.Left;
_frmFullscreenRenderer.Size = screenSize;
_frmFullscreenRenderer.Show();
}
}
}