Skip to content

Commit

Permalink
better fix for the ugly line of menu in windows 10
Browse files Browse the repository at this point in the history
  • Loading branch information
d2phap committed Apr 24, 2022
1 parent 736559e commit 8fcf218
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 107 deletions.
19 changes: 19 additions & 0 deletions v9/Components/ImageGlass.Base/Helpers/Visual.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,23 @@ public static Color ChangeColorBrightness(Color color, float correctionFactor)

return Color.FromArgb(color.A, (byte)red, (byte)green, (byte)blue);
}


/// <summary>
/// Gets menu item border radius
/// </summary>
/// <param name="itemHeight"></param>
/// <returns></returns>
public static int GetItemBorderRadius(int itemHeight, int defaultItemHeight)
{
if (IsOS(WindowsOS.Win10))
{
return 0;
}

var radius = (int)(itemHeight * 1.0f / defaultItemHeight * 3);

// min border radius = 4
return Math.Max(radius, 4);
}
}
121 changes: 64 additions & 57 deletions v9/Components/ImageGlass.UI/Menu/ModernMenu.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ namespace ImageGlass.UI;
public class ModernMenu : ContextMenuStrip
{
private IgTheme _theme = new();
private bool _isFixedUnwantedBorder = false;


#region Public properties
Expand All @@ -50,7 +49,7 @@ public IgTheme Theme
/// <summary>
/// Gets all items excluding <c>ToolStripSeparator</c> items.
/// </summary>
public IEnumerable<ToolStripItem> ActualItems => GetActualItems(Items);
public IEnumerable<ToolStripItem> ActualItems => MenuUtils.GetActualItems(Items);

#endregion

Expand All @@ -64,28 +63,17 @@ public ModernMenu(IContainer container) : base(container)

#region Protected override

protected override void OnLayoutCompleted(EventArgs e)
{
base.OnLayoutCompleted(e);

// fix unwanted top-left border by shifting the region to (1,1)
if (!_isFixedUnwantedBorder && !DesignMode)
{
_isFixedUnwantedBorder = true;
var path = new System.Drawing.Drawing2D.GraphicsPath();
path.AddRectangle(new RectangleF(0.05f, 0.05f,
DpiApi.Transform(Width), DpiApi.Transform(Height)));

Region = new Region(path);
}
}

protected override void OnItemAdded(ToolStripItemEventArgs e)
{
base.OnItemAdded(e);

// manually control the height og menu by disable image scaling
e.Item.ImageScaling = ToolStripItemImageScaling.None;

if (e.Item is ToolStripMenuItem item)
{
item.DropDown.Renderer = new ModernMenuRenderer(Theme);
}
}

protected override void OnOpening(CancelEventArgs e)
Expand All @@ -94,28 +82,24 @@ protected override void OnOpening(CancelEventArgs e)

if (!DesignMode)
{
FixGeneralIssues(toFixDpiSize: true, toFixDropdown: true);
FixGeneralIssues(toFixDpiSize: true,toFixDropdown: true);
}
}

#endregion
protected override void OnOpened(EventArgs e)
{
base.OnOpened(e);

if (!DesignMode)
{
FixGeneralIssues(toFixUnwantedBorder: true);
}
}

#region Public function
#endregion

/// <summary>
/// Apply these fixes:
/// <list type="bullet">
/// <item>Menu height when DPI changes</item>
/// <item>Windows 11 round border</item>
/// <item>Dropdown direction</item>
/// </list>
/// </summary>
public void FixGeneralIssues(bool toFixDpiSize = false, bool toFixDropdown = false)
{
FixGeneralIssues(ActualItems, toFixDpiSize, toFixDropdown);
}

#region Public function

/// <summary>
/// Apply these fixes:
Expand All @@ -124,15 +108,14 @@ public void FixGeneralIssues(bool toFixDpiSize = false, bool toFixDropdown = fal
/// <item>Windows 11 round border</item>
/// <item>Dropdown direction</item>
/// </list>
/// to the <see cref="ModernMenu"/> component.
/// </summary>
/// <param name="coll"></param>
public void FixGeneralIssues(ToolStripItemCollection coll,
public void FixGeneralIssues(
bool toFixDpiSize = false,
bool toFixDropdown = false)
bool toFixDropdown = false,
bool toFixUnwantedBorder = false)
{
var items = GetActualItems(coll);

FixGeneralIssues(items, toFixDpiSize, toFixDropdown);
FixGeneralIssues(this, toFixDpiSize, toFixDropdown, toFixUnwantedBorder);
}


Expand All @@ -143,20 +126,31 @@ public void FixGeneralIssues(ToolStripItemCollection coll,
/// <item>Windows 11 round border</item>
/// <item>Dropdown direction</item>
/// </list>
/// to the provided menu component.
/// </summary>
/// <param name="items"></param>
public void FixGeneralIssues(
IEnumerable<ToolStripItem> items,
ToolStripDropDown menu,
bool toFixDpiSize = false,
bool toFixDropdown = false)
bool toFixDropdown = false,
bool toFixUnwantedBorder = false)
{
if (!items.Any()) return;
//// fix unwanted top-left border by shifting the region to (1,1)
//if (toFixUnwantedBorder)
//{
// menu.Region = GetCorrectMenuRegion(menu);
//}

if (!toFixDpiSize && !toFixDropdown) return;

var allItems = MenuUtils.GetActualItems(menu.Items);
if (!allItems.Any()) return;

// standard icon size
var iconH = DpiApi.Transform(Constants.MENU_ICON_HEIGHT);
var standardIcon = new Bitmap(iconH, iconH);

foreach (ToolStripMenuItem item in items)
foreach (ToolStripMenuItem item in allItems)
{
#region Fix menu height
if (toFixDpiSize)
Expand All @@ -183,23 +177,36 @@ public void FixGeneralIssues(
// apply corner
CornerApi.ApplyCorner(item.DropDown.Handle);

// set background
item.DropDown.BackColor = Theme.Settings.MenuBgColor;

// fix dropdown direction
item.DropDownOpening -= Item_DropDownOpening;
item.DropDownOpening += Item_DropDownOpening;
item.DropDownOpened += Item_DropDownOpened;

// fix dropdown items
FixGeneralIssues(item.DropDownItems, toFixDpiSize, toFixDropdown);
FixGeneralIssues(item.DropDown, toFixDpiSize, toFixDropdown);
}
}

}

private void Item_DropDownOpened(object? sender, EventArgs e)
{
var mnuItem = sender as ToolStripMenuItem;
if (mnuItem is null || !mnuItem.HasDropDownItems)
{
return; // not a dropdown item
}

//// fix unwanted top-left border by shifting the region to (1,1)
//FixGeneralIssues(mnuItem.DropDown, toFixUnwantedBorder: true);

}

#endregion


#region Private functions

private void Item_DropDownOpening(object? sender, EventArgs e)
{
var mnuItem = sender as ToolStripMenuItem;
Expand Down Expand Up @@ -247,22 +254,22 @@ private void Item_DropDownOpening(object? sender, EventArgs e)
#endregion
}

#endregion


#region Public static functions

/// <summary>
/// Gets all items excluding <c>ToolStripSeparator</c> items.
/// Fix unwanted top-left border by shifting the region to (1,1)
/// </summary>
/// <param name="coll"></param>
/// <param name="menu"></param>
/// <returns></returns>
public static IEnumerable<ToolStripItem> GetActualItems(ToolStripItemCollection coll)
private Region GetCorrectMenuRegion(ToolStripDropDown menu)
{
return coll
.Cast<ToolStripItem>()
.Where(item => item.GetType() != typeof(ToolStripSeparator));
var path = new System.Drawing.Drawing2D.GraphicsPath();
path.AddRectangle(new RectangleF(0.05f, 0.05f,
DpiApi.Transform(Width), DpiApi.Transform(Height)));

return new Region(path);
}

#endregion


}
112 changes: 62 additions & 50 deletions v9/Components/ImageGlass.UI/Menu/ModernMenuRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,25 +29,11 @@ public class ModernMenuRenderer : ToolStripProfessionalRenderer
private IgTheme _theme { get; set; }



public ModernMenuRenderer(IgTheme theme) : base(new ModernMenuColors(theme))
{
_theme = theme;
}

private int BorderRadius(int itemHeight)
{
if (Helpers.IsOS(WindowsOS.Win10))
{
return 0;
}

var radius = (int)(itemHeight * 1.0f / Constants.MENU_ICON_HEIGHT * 3);

// min border radius = 5
return Math.Max(radius, 5);
}

protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e)
{
if (e.Item.Enabled)
Expand Down Expand Up @@ -110,41 +96,6 @@ protected override void OnRenderSeparator(ToolStripSeparatorRenderEventArgs e)
}
}

protected override void OnRenderToolStripBackground(ToolStripRenderEventArgs e)
{
if (e.ToolStrip is ToolStripDropDown)
{
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;

// draw background
using var brush = new SolidBrush(_theme.Settings.MenuBgColor);
e.Graphics.FillRectangle(brush, e.AffectedBounds);

// draw border
using var pen = new Pen(Color.Black);
if (_theme.Settings.MenuBgColor.GetBrightness() > 0.5) // light background color
{
pen.Color = Color.FromArgb(35, 0, 0, 0);
}
else // dark background color
{
pen.Color = Color.FromArgb(35, 255, 255, 255);
}

const int UNWANTED_BORDER_WIDTH = 1;

e.Graphics.DrawRectangle(pen,
UNWANTED_BORDER_WIDTH,
UNWANTED_BORDER_WIDTH,
e.AffectedBounds.Width - 1 - UNWANTED_BORDER_WIDTH,
e.AffectedBounds.Height - 1 - UNWANTED_BORDER_WIDTH);
}
else
{
base.OnRenderToolStripBackground(e);
}
}

protected override void OnRenderArrow(ToolStripArrowRenderEventArgs e)
{
var textColor = e.Item.Selected ? _theme.Settings.MenuTextHoverColor : _theme.Settings.MenuTextColor;
Expand Down Expand Up @@ -242,7 +193,7 @@ protected override void OnRenderMenuItemBackground(ToolStripItemRenderEventArgs
e.Item.Bounds.Height - 5);

using var brush = new SolidBrush(_theme.Settings.MenuBgHoverColor);
using var path = ThemeUtils.GetRoundRectanglePath(rect, BorderRadius(rect.Height));
using var path = ThemeUtils.GetRoundRectanglePath(rect, Helpers.GetItemBorderRadius(rect.Height, Constants.MENU_ICON_HEIGHT));
using var penBorder = new Pen(Color.FromArgb(brush.Color.A, brush.Color));

// draw
Expand All @@ -255,7 +206,68 @@ protected override void OnRenderMenuItemBackground(ToolStripItemRenderEventArgs
{
base.OnRenderMenuItemBackground(e);
}
}


// render menu dropdown background
protected override void OnRenderToolStripBackground(ToolStripRenderEventArgs e)
{
if (e.ToolStrip is ToolStripDropDown)
{
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;

// draw background
using var brush = new SolidBrush(_theme.Settings.MenuBgColor);
e.Graphics.FillRectangle(brush, e.AffectedBounds);
}
else
{
base.OnRenderToolStripBackground(e);
}
}


// render menu dropdown border
protected override void OnRenderToolStripBorder(ToolStripRenderEventArgs e)
{
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;

if (Helpers.IsOS(WindowsOS.Win10))
{
// override default ugly border by a solid color
using var penDefault = new Pen(_theme.Settings.MenuBgColor);
e.Graphics.DrawRectangle(penDefault,
0,
0,
e.AffectedBounds.Width,
e.AffectedBounds.Height);
}
else
{
base.OnRenderToolStripBorder(e);
}

using var pen = new Pen(_theme.Settings.MenuBgColor);

if (_theme.Settings.MenuBgColor.GetBrightness() > 0.5) // light background
{
pen.Color = Color.FromArgb(35, 0, 0, 0);
}
else // dark background
{
pen.Color = Color.FromArgb(35, 255, 255, 255);
}

var menuBorderRadius = Helpers.IsOS(WindowsOS.Win11) ? 8 : 0;
using var path = ThemeUtils.GetRoundRectanglePath(new()
{
X = 0,
Y = 0,
Width = e.AffectedBounds.Width - 1,
Height = e.AffectedBounds.Height - 1,
}, menuBorderRadius);

e.Graphics.DrawPath(pen, path);
}

}

0 comments on commit 8fcf218

Please sign in to comment.