Linux: Integrate some of Mesen's code to fix usability issues with menu/tool bars and improve the look of some controls
This commit is contained in:
parent
97571c94bc
commit
95199f5f62
5 changed files with 373 additions and 2 deletions
|
@ -41,8 +41,6 @@ namespace Mesen.GUI.Debugger
|
|||
|
||||
protected override void OnLoad(EventArgs e)
|
||||
{
|
||||
base.OnLoad(e);
|
||||
|
||||
_notifListener = new NotificationListener();
|
||||
_notifListener.OnNotification += OnNotificationReceived;
|
||||
|
||||
|
@ -89,6 +87,8 @@ namespace Mesen.GUI.Debugger
|
|||
|
||||
BreakpointManager.AddCpuType(_cpuType);
|
||||
DebugApi.Step(_cpuType, 10000, StepType.Step);
|
||||
|
||||
base.OnLoad(e);
|
||||
}
|
||||
|
||||
protected override void OnClosing(CancelEventArgs e)
|
||||
|
|
|
@ -25,6 +25,7 @@ namespace Mesen.GUI.Forms
|
|||
public BaseForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
MonoThemeHelper.InitTheme(Color.White);
|
||||
}
|
||||
|
||||
public virtual bool IsConfigForm { get { return false; } }
|
||||
|
@ -88,6 +89,8 @@ namespace Mesen.GUI.Forms
|
|||
}
|
||||
}
|
||||
|
||||
MonoThemeHelper.FixMonoColors(this);
|
||||
|
||||
int tabIndex = 0;
|
||||
InitializeTabIndexes(this, ref tabIndex);
|
||||
ResourceHelper.ApplyResources(this);
|
||||
|
|
290
UI/Forms/MonoThemeHelper.cs
Normal file
290
UI/Forms/MonoThemeHelper.cs
Normal file
|
@ -0,0 +1,290 @@
|
|||
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
|
||||
{
|
||||
public static class MonoThemeHelper
|
||||
{
|
||||
public static MonoTheme Theme { get; private set; } = new MonoTheme();
|
||||
private static Dictionary<string, List<WeakReference<object>>> _excludedControls = new Dictionary<string, List<WeakReference<object>>>();
|
||||
|
||||
public static void InitTheme(Color backColor)
|
||||
{
|
||||
if(backColor.R < 128 && backColor.G < 128 && backColor.B < 128) {
|
||||
Theme = new DarkMonoTheme();
|
||||
} else {
|
||||
Theme = new MonoTheme();
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsDark { get { return Theme is DarkMonoTheme; } }
|
||||
|
||||
public static void ExcludeFromTheme(Control ctrl)
|
||||
{
|
||||
if(Program.IsMono) {
|
||||
List<WeakReference<object>> refList;
|
||||
if(!_excludedControls.TryGetValue(ctrl.Name, out refList)) {
|
||||
refList = new List<WeakReference<object>>();
|
||||
_excludedControls[ctrl.Name] = refList;
|
||||
}
|
||||
refList.Add(new WeakReference<object>(ctrl));
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsExcludedFromTheme(Control ctrl)
|
||||
{
|
||||
if(Program.IsMono) {
|
||||
List<WeakReference<object>> refList;
|
||||
if(_excludedControls.TryGetValue(ctrl.Name, out refList)) {
|
||||
foreach(WeakReference<object> weakRef in refList) {
|
||||
object target;
|
||||
if(weakRef.TryGetTarget(out target)) {
|
||||
return target == ctrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void FixMonoColors(Form form)
|
||||
{
|
||||
if(Program.IsMono) {
|
||||
form.BackColor = Theme.FormBgColor;
|
||||
FixMonoColors(form, Theme);
|
||||
}
|
||||
}
|
||||
|
||||
public static void FixMonoColors(ContextMenuStrip menu)
|
||||
{
|
||||
if(Program.IsMono) {
|
||||
if(menu.Tag == null || (bool)menu.Tag != true) {
|
||||
//Only process this context menu a single time (uses its Tag to know if we've processed it or not)
|
||||
FixMonoColors(menu, Theme);
|
||||
menu.Tag = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void FixMonoColors(ToolStripItem item, MonoTheme theme)
|
||||
{
|
||||
item.ForeColor = item.Enabled ? theme.ToolStripItemForeColor : theme.ToolStripItemDisabledForeColor;
|
||||
item.BackColor = theme.ToolStripItemBgColor;
|
||||
item.Font = new Font("Microsoft Sans Serif", 8.25f);
|
||||
|
||||
item.EnabledChanged += (object sender, EventArgs e) => {
|
||||
((ToolStripItem)sender).ForeColor = ((ToolStripItem)sender).Enabled ? theme.ToolStripItemForeColor : theme.ToolStripItemDisabledForeColor;
|
||||
};
|
||||
|
||||
if(item is ToolStripDropDownItem) {
|
||||
ToolStripDropDownItem ddItem = item as ToolStripDropDownItem;
|
||||
|
||||
ddItem.DropDownOpening += MonoToolStripHelper.DropdownOpening;
|
||||
ddItem.DropDownClosed += MonoToolStripHelper.DropdownClosed;
|
||||
|
||||
ddItem.DropDownOpening += (s, e) => {
|
||||
ddItem.DropDown.BackColor = theme.ToolStripItemBgColor;
|
||||
foreach(ToolStripItem subItem in ddItem.DropDownItems) {
|
||||
FixMonoColors(subItem, theme);
|
||||
}
|
||||
};
|
||||
|
||||
foreach(ToolStripItem subItem in ddItem.DropDownItems) {
|
||||
FixMonoColors(subItem, theme);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void FixMonoColors(Control container, MonoTheme theme)
|
||||
{
|
||||
if(MonoThemeHelper.IsExcludedFromTheme(container)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(container is TextBox) {
|
||||
TextBox txt = (TextBox)container;
|
||||
txt.BorderStyle = BorderStyle.FixedSingle;
|
||||
txt.BackColor = txt.ReadOnly ? theme.TextBoxDisabledBgColor : theme.TextBoxEnabledBgColor;
|
||||
txt.ForeColor = theme.TextBoxForeColor;
|
||||
txt.ReadOnlyChanged += (object sender, EventArgs e) => {
|
||||
((TextBox)sender).BackColor = ((TextBox)sender).ReadOnly ? theme.TextBoxDisabledBgColor : theme.TextBoxEnabledBgColor;
|
||||
};
|
||||
} else if(container is Label) {
|
||||
Label lbl = (Label)container;
|
||||
if(lbl.BackColor == Color.White) {
|
||||
//Trackbar labels
|
||||
lbl.BackColor = theme.TextBoxEnabledBgColor;
|
||||
lbl.ForeColor = theme.TextBoxForeColor;
|
||||
} else {
|
||||
if(lbl.ForeColor == SystemColors.GrayText) {
|
||||
//Headers
|
||||
lbl.ForeColor = theme.GrayTextColor;
|
||||
} else if(lbl.ForeColor == SystemColors.ControlDark) {
|
||||
//ctrlRiskyOption
|
||||
lbl.ForeColor = theme.DarkTextColor;
|
||||
} else {
|
||||
//Regular label
|
||||
lbl.ForeColor = lbl.Enabled ? theme.LabelForeColor : theme.LabelDisabledForeColor;
|
||||
lbl.EnabledChanged += (object sender, EventArgs e) => {
|
||||
((Label)sender).ForeColor = ((Label)sender).Enabled ? theme.LabelForeColor : theme.LabelDisabledForeColor;
|
||||
};
|
||||
}
|
||||
}
|
||||
} else if(container is CheckBox) {
|
||||
CheckBox chk = (CheckBox)container;
|
||||
chk.FlatStyle = FlatStyle.Flat;
|
||||
chk.ForeColor = chk.Enabled ? theme.LabelForeColor : theme.LabelDisabledForeColor;
|
||||
if(chk.BackColor == SystemColors.ControlLightLight) {
|
||||
//Enable equalizer checkbox
|
||||
chk.BackColor = theme.TabBgColor;
|
||||
}
|
||||
chk.EnabledChanged += (object sender, EventArgs e) => {
|
||||
((CheckBox)sender).ForeColor = ((CheckBox)sender).Enabled ? theme.LabelForeColor : theme.LabelDisabledForeColor;
|
||||
};
|
||||
} else if(container is RadioButton) {
|
||||
((RadioButton)container).ForeColor = ((RadioButton)container).Enabled ? theme.LabelForeColor : theme.LabelDisabledForeColor;
|
||||
((RadioButton)container).EnabledChanged += (object sender, EventArgs e) => {
|
||||
((RadioButton)sender).ForeColor = ((RadioButton)sender).Enabled ? theme.LabelForeColor : theme.LabelDisabledForeColor;
|
||||
};
|
||||
} else if(container is TrackBar) {
|
||||
((TrackBar)container).BackColor = theme.TabBgColor;
|
||||
} else if(container is Button) {
|
||||
Button btn = (Button)container;
|
||||
btn.FlatStyle = FlatStyle.Flat;
|
||||
btn.BackColor = btn.Enabled ? theme.ButtonEnabledBgColor : theme.ButtonDisabledBgColor;
|
||||
btn.ForeColor = theme.ButtonForeColor;
|
||||
|
||||
btn.EnabledChanged += (object sender, EventArgs e) => {
|
||||
((Button)sender).BackColor = ((Button)sender).Enabled ? theme.ButtonEnabledBgColor : theme.ButtonDisabledBgColor;
|
||||
};
|
||||
} else if(container is ComboBox) {
|
||||
ComboBox cbo = (ComboBox)container;
|
||||
cbo.FlatStyle = FlatStyle.Flat;
|
||||
cbo.BackColor = cbo.Enabled ? theme.ComboEnabledBgColor : theme.ComboDisabledBgColor;
|
||||
cbo.ForeColor = theme.TextBoxForeColor;
|
||||
cbo.EnabledChanged += (object sender, EventArgs e) => {
|
||||
((ComboBox)sender).BackColor = ((ComboBox)sender).Enabled ? theme.ComboEnabledBgColor : theme.ComboDisabledBgColor;
|
||||
};
|
||||
} else if(container is GroupBox) {
|
||||
((GroupBox)container).ForeColor = theme.LabelForeColor;
|
||||
} else if(container is TabControl) {
|
||||
((TabControl)container).BackColor = theme.TabBgColor;
|
||||
} else if(container is TabPage) {
|
||||
((TabPage)container).BackColor = theme.TabBgColor;
|
||||
} else if(container is Panel && !(container is TableLayoutPanel) && !(container is FlowLayoutPanel)) {
|
||||
((Panel)container).BackColor = theme.PanelBgColor;
|
||||
} else if(container is DataGridView) {
|
||||
DataGridView dgv = (DataGridView)container;
|
||||
dgv.BackgroundColor = theme.ListBgColor;
|
||||
dgv.ForeColor = theme.LabelForeColor;
|
||||
dgv.GridColor = theme.LabelForeColor;
|
||||
dgv.DefaultCellStyle.ForeColor = theme.LabelForeColor;
|
||||
dgv.DefaultCellStyle.BackColor = theme.ListBgColor;
|
||||
dgv.ColumnHeadersDefaultCellStyle.ForeColor = theme.LabelForeColor;
|
||||
dgv.ColumnHeadersDefaultCellStyle.BackColor = theme.TabBgColor;
|
||||
} else if(container is DataGridTextBox) {
|
||||
((DataGridTextBox)container).BackColor = theme.TextBoxEnabledBgColor;
|
||||
((DataGridTextBox)container).ForeColor = theme.TextBoxForeColor;
|
||||
} else if(container is ListView) {
|
||||
((ListView)container).BackColor = theme.ListBgColor;
|
||||
((ListView)container).ForeColor = theme.LabelForeColor;
|
||||
} else if(container is ToolStrip) {
|
||||
((ToolStrip)container).BackColor = theme.FormBgColor;
|
||||
|
||||
if(container is ContextMenuStrip) {
|
||||
((ContextMenuStrip)container).Opening += MonoToolStripHelper.ContextMenuOpening;
|
||||
((ContextMenuStrip)container).Closed += MonoToolStripHelper.ContextMenuClosed;
|
||||
} else {
|
||||
((ToolStrip)container).RenderMode = ToolStripRenderMode.System;
|
||||
}
|
||||
|
||||
foreach(ToolStripItem item in ((ToolStrip)container).Items) {
|
||||
FixMonoColors(item, theme);
|
||||
}
|
||||
}
|
||||
|
||||
if(container.ContextMenuStrip != null) {
|
||||
container.ContextMenuStrip.Opening += MonoToolStripHelper.ContextMenuOpening;
|
||||
container.ContextMenuStrip.Closed += MonoToolStripHelper.ContextMenuClosed;
|
||||
|
||||
foreach(ToolStripItem item in container.ContextMenuStrip.Items) {
|
||||
FixMonoColors(item, theme);
|
||||
}
|
||||
}
|
||||
|
||||
foreach(Control ctrl in container.Controls) {
|
||||
FixMonoColors(ctrl, theme);
|
||||
}
|
||||
}
|
||||
|
||||
public class MonoTheme
|
||||
{
|
||||
public virtual Color TextBoxDisabledBgColor { get; } = Color.FromArgb(240, 240, 240);
|
||||
public virtual Color TextBoxEnabledBgColor { get; } = Color.FromArgb(255, 255, 255);
|
||||
public virtual Color TextBoxForeColor { get; } = Color.FromArgb(0, 0, 0);
|
||||
|
||||
public virtual Color ButtonDisabledBgColor { get; } = Color.FromArgb(180, 180, 180);
|
||||
public virtual Color ButtonEnabledBgColor { get; } = Color.FromArgb(230, 230, 230);
|
||||
public virtual Color ButtonForeColor { get; } = Color.FromArgb(0, 0, 0);
|
||||
|
||||
public virtual Color LabelForeColor { get; } = Program.IsMono ? Color.Black : SystemColors.ControlText;
|
||||
public virtual Color LabelDisabledForeColor { get; } = Color.Gray;
|
||||
public virtual Color ErrorTextColor { get; } = Color.Red;
|
||||
public virtual Color GrayTextColor { get; } = Program.IsMono ? Color.Gray : SystemColors.GrayText;
|
||||
public virtual Color DarkTextColor { get; } = Program.IsMono ? Color.LightGray : SystemColors.ControlDark;
|
||||
public virtual Color LinkTextColor { get; } = Color.FromArgb(61, 125, 255);
|
||||
|
||||
public virtual Color ComboEnabledBgColor { get; } = Color.FromArgb(230, 230, 230);
|
||||
public virtual Color ComboDisabledBgColor { get; } = Color.FromArgb(180, 180, 180);
|
||||
|
||||
public virtual Color FormBgColor { get; } = Program.IsMono ? Color.FromArgb(239, 240, 241) : SystemColors.Control;
|
||||
public virtual Color TabBgColor { get; } = Program.IsMono ? Color.White : Color.Transparent;
|
||||
public virtual Color PanelBgColor { get; } = Program.IsMono ? Color.FromArgb(239, 240, 241) : SystemColors.Control;
|
||||
public virtual Color ListBgColor { get; } = Program.IsMono ? Color.White : SystemColors.ControlLightLight;
|
||||
|
||||
public virtual Color ToolStripItemBgColor { get; } = Program.IsMono ? Color.FromArgb(239, 240, 241) : SystemColors.Control;
|
||||
public virtual Color ToolStripItemForeColor { get; } = Color.Black;
|
||||
public virtual Color ToolStripItemDisabledForeColor { get; } = Color.Gray;
|
||||
}
|
||||
|
||||
class DarkMonoTheme : MonoTheme
|
||||
{
|
||||
private static readonly Color TextColor = Color.FromArgb(255, 255, 255);
|
||||
private static readonly Color MainBgColor = Color.FromArgb(49, 54, 69);
|
||||
private static readonly Color HighlightBgColor = Color.FromArgb(69, 73, 70);
|
||||
private static readonly Color HighlightDisabledBgColor = Color.FromArgb(47, 52, 57);
|
||||
|
||||
public override Color TextBoxDisabledBgColor { get; } = DarkMonoTheme.HighlightDisabledBgColor;
|
||||
public override Color TextBoxEnabledBgColor { get; } = Color.FromArgb(69, 73, 78);
|
||||
public override Color TextBoxForeColor { get; } = DarkMonoTheme.TextColor;
|
||||
|
||||
public override Color ButtonDisabledBgColor { get; } = DarkMonoTheme.HighlightDisabledBgColor;
|
||||
public override Color ButtonEnabledBgColor { get; } = DarkMonoTheme.HighlightBgColor;
|
||||
public override Color ButtonForeColor { get; } = DarkMonoTheme.TextColor;
|
||||
|
||||
public override Color LabelForeColor { get; } = DarkMonoTheme.TextColor;
|
||||
public override Color LabelDisabledForeColor { get; } = Color.Gray;
|
||||
public override Color ErrorTextColor { get; } = Color.IndianRed;
|
||||
public override Color GrayTextColor { get; } = Color.LightGray;
|
||||
public override Color DarkTextColor { get; } = Color.LightGray;
|
||||
public override Color LinkTextColor { get; } = Color.FromArgb(61, 125, 255);
|
||||
|
||||
public override Color ComboEnabledBgColor { get; } = Color.FromArgb(69, 73, 78);
|
||||
public override Color ComboDisabledBgColor { get; } = Color.FromArgb(47, 52, 47);
|
||||
|
||||
public override Color FormBgColor { get; } = DarkMonoTheme.MainBgColor;
|
||||
public override Color TabBgColor { get; } = Color.FromArgb(45, 49, 54);
|
||||
public override Color PanelBgColor { get; } = DarkMonoTheme.MainBgColor;
|
||||
public override Color ListBgColor { get; } = Color.FromArgb(45, 49, 54);
|
||||
|
||||
public override Color ToolStripItemBgColor { get; } = DarkMonoTheme.MainBgColor;
|
||||
public override Color ToolStripItemForeColor { get; } = DarkMonoTheme.TextColor;
|
||||
public override Color ToolStripItemDisabledForeColor { get; } = Color.Gray;
|
||||
}
|
||||
}
|
||||
}
|
76
UI/Forms/MonoToolStripHelper.cs
Normal file
76
UI/Forms/MonoToolStripHelper.cs
Normal file
|
@ -0,0 +1,76 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Mesen.GUI
|
||||
{
|
||||
//Everything in here is a workaround for issues with dropdown menus in the latest version of Mono (5.18)
|
||||
//Bug report:
|
||||
//https://github.com/mono/mono/issues/12644
|
||||
static class MonoToolStripHelper
|
||||
{
|
||||
private static HashSet<ToolStripDropDown> _openedDropdowns = new HashSet<ToolStripDropDown>();
|
||||
|
||||
public static void DropdownOpening(object sender, EventArgs e)
|
||||
{
|
||||
ToolStripDropDownItem ddItem = (ToolStripDropDownItem)sender;
|
||||
if(!ddItem.GetCurrentParent().Visible) {
|
||||
ddItem.DropDown.Close();
|
||||
return;
|
||||
}
|
||||
|
||||
HashSet<object> parents = new HashSet<object>();
|
||||
parents.Add(ddItem.GetCurrentParent());
|
||||
ToolStripItem parent = ddItem.OwnerItem;
|
||||
if(parent != null) {
|
||||
parents.Add(parent);
|
||||
parents.Add(parent.GetCurrentParent());
|
||||
while((parent = parent.OwnerItem) != null) {
|
||||
parents.Add(parent);
|
||||
parents.Add(parent.GetCurrentParent());
|
||||
}
|
||||
}
|
||||
|
||||
foreach(ToolStripDropDown openedDropdown in _openedDropdowns.ToList()) {
|
||||
//Close all non-parent dropdowns when opening a new dropdown
|
||||
if(!parents.Contains(openedDropdown.OwnerItem) && !parents.Contains(openedDropdown)) {
|
||||
openedDropdown.Close();
|
||||
}
|
||||
}
|
||||
|
||||
_openedDropdowns.Add(ddItem.DropDown);
|
||||
}
|
||||
|
||||
public static void DropdownClosed(object sender, EventArgs e)
|
||||
{
|
||||
ToolStripDropDownItem ddItem = (ToolStripDropDownItem)sender;
|
||||
ToolStripDropDown parent = ddItem.GetCurrentParent() as ToolStripDropDown;
|
||||
if(parent != null) {
|
||||
Point pos = parent.PointToClient(Cursor.Position);
|
||||
if(pos.X < 0 || pos.Y < 0 || pos.X > parent.Width || pos.Y > parent.Height) {
|
||||
//When closing a dropdown, if the mouse isn't inside its parent, close all the parent, too.
|
||||
parent.Close();
|
||||
}
|
||||
}
|
||||
|
||||
_openedDropdowns.Remove(ddItem.DropDown);
|
||||
}
|
||||
|
||||
public static void ContextMenuOpening(object sender, EventArgs e)
|
||||
{
|
||||
//Close all existing dropdowns with no exception when a context menu opens
|
||||
foreach(ToolStripDropDown openedDropdown in _openedDropdowns.ToList()) {
|
||||
openedDropdown.Close();
|
||||
}
|
||||
_openedDropdowns = new HashSet<ToolStripDropDown>();
|
||||
_openedDropdowns.Add((ContextMenuStrip)sender);
|
||||
}
|
||||
|
||||
public static void ContextMenuClosed(object sender, EventArgs e)
|
||||
{
|
||||
_openedDropdowns.Remove((ContextMenuStrip)sender);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -800,6 +800,8 @@
|
|||
<Compile Include="Forms\Config\frmRecordMovie.Designer.cs">
|
||||
<DependentUpon>frmRecordMovie.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\MonoThemeHelper.cs" />
|
||||
<Compile Include="Forms\MonoToolStripHelper.cs" />
|
||||
<Compile Include="Forms\NetPlay\frmClientConfig.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
|
|
Loading…
Add table
Reference in a new issue