From 148d3885ada8c0729af23cfd1d661438df542473 Mon Sep 17 00:00:00 2001 From: celeron533 Date: Sat, 6 Jul 2019 21:17:03 +0800 Subject: [PATCH] Code refactoring: Notification tray icon --- .../Properties/Resources.Designer.cs | 28 +-- shadowsocks-csharp/Properties/Resources.resx | 19 +- shadowsocks-csharp/Resources/ss128.pdn | Bin 0 -> 15863 bytes shadowsocks-csharp/Resources/ss16.png | Bin 376 -> 0 bytes shadowsocks-csharp/Resources/ss20.png | Bin 411 -> 0 bytes shadowsocks-csharp/Resources/ss24.png | Bin 492 -> 0 bytes shadowsocks-csharp/Resources/ss32.pdn | Bin 0 -> 7187 bytes shadowsocks-csharp/Resources/ss32Fill.png | Bin 0 -> 617 bytes shadowsocks-csharp/Resources/ss32In.png | Bin 0 -> 211 bytes shadowsocks-csharp/Resources/ss32Out.png | Bin 0 -> 215 bytes shadowsocks-csharp/Resources/ss32Outline.png | Bin 0 -> 787 bytes shadowsocks-csharp/Resources/ssIn24.png | Bin 225 -> 0 bytes shadowsocks-csharp/Resources/ssOut24.png | Bin 239 -> 0 bytes shadowsocks-csharp/Util/Util.cs | 14 +- shadowsocks-csharp/Util/ViewUtils.cs | 134 +++++++++--- shadowsocks-csharp/View/MenuViewController.cs | 204 ++++++++---------- shadowsocks-csharp/shadowsocks-csharp.csproj | 19 +- 17 files changed, 224 insertions(+), 194 deletions(-) create mode 100644 shadowsocks-csharp/Resources/ss128.pdn delete mode 100755 shadowsocks-csharp/Resources/ss16.png delete mode 100755 shadowsocks-csharp/Resources/ss20.png delete mode 100755 shadowsocks-csharp/Resources/ss24.png create mode 100644 shadowsocks-csharp/Resources/ss32.pdn create mode 100644 shadowsocks-csharp/Resources/ss32Fill.png create mode 100644 shadowsocks-csharp/Resources/ss32In.png create mode 100644 shadowsocks-csharp/Resources/ss32Out.png create mode 100644 shadowsocks-csharp/Resources/ss32Outline.png delete mode 100644 shadowsocks-csharp/Resources/ssIn24.png delete mode 100644 shadowsocks-csharp/Resources/ssOut24.png diff --git a/shadowsocks-csharp/Properties/Resources.Designer.cs b/shadowsocks-csharp/Properties/Resources.Designer.cs index 9c931553..5740858f 100644 --- a/shadowsocks-csharp/Properties/Resources.Designer.cs +++ b/shadowsocks-csharp/Properties/Resources.Designer.cs @@ -116,7 +116,7 @@ namespace Shadowsocks.Properties { ///logfile ss_privoxy.log ///show-on-task-bar 0 ///activity-animation 0 - ///forward-socks5 / 127.0.0.1:__SOCKS_PORT__ . + ///forward-socks5 / __SOCKS_HOST__:__SOCKS_PORT__ . ///max-client-connections 2048 ///hide-console ///. @@ -150,9 +150,9 @@ namespace Shadowsocks.Properties { /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// - internal static System.Drawing.Bitmap ss16 { + internal static System.Drawing.Bitmap ss32Fill { get { - object obj = ResourceManager.GetObject("ss16", resourceCulture); + object obj = ResourceManager.GetObject("ss32Fill", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } @@ -160,9 +160,9 @@ namespace Shadowsocks.Properties { /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// - internal static System.Drawing.Bitmap ss20 { + internal static System.Drawing.Bitmap ss32In { get { - object obj = ResourceManager.GetObject("ss20", resourceCulture); + object obj = ResourceManager.GetObject("ss32In", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } @@ -170,9 +170,9 @@ namespace Shadowsocks.Properties { /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// - internal static System.Drawing.Bitmap ss24 { + internal static System.Drawing.Bitmap ss32Out { get { - object obj = ResourceManager.GetObject("ss24", resourceCulture); + object obj = ResourceManager.GetObject("ss32Out", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } @@ -180,19 +180,9 @@ namespace Shadowsocks.Properties { /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// - internal static System.Drawing.Bitmap ssIn24 { + internal static System.Drawing.Bitmap ss32Outline { get { - object obj = ResourceManager.GetObject("ssIn24", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap ssOut24 { - get { - object obj = ResourceManager.GetObject("ssOut24", resourceCulture); + object obj = ResourceManager.GetObject("ss32Outline", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } diff --git a/shadowsocks-csharp/Properties/Resources.resx b/shadowsocks-csharp/Properties/Resources.resx index f95c473e..081bd8d8 100755 --- a/shadowsocks-csharp/Properties/Resources.resx +++ b/shadowsocks-csharp/Properties/Resources.resx @@ -136,20 +136,17 @@ ..\Data\proxy.pac.txt.gz;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - ..\Resources\ss16.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\ss32Fill.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\ss20.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\ss32In.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\ss24.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\ss32Out.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\ssIn24.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\ssOut24.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\ss32Outline.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\ssw128.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a diff --git a/shadowsocks-csharp/Resources/ss128.pdn b/shadowsocks-csharp/Resources/ss128.pdn new file mode 100644 index 0000000000000000000000000000000000000000..5fa50a374cb9c4d85b179e9ab36aa7a139f7eddf GIT binary patch literal 15863 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 FV1mKBpOOFo diff --git a/shadowsocks-csharp/Resources/ss24.png b/shadowsocks-csharp/Resources/ss24.png deleted file mode 100755 index 9a155ff15e0b46cb4397460aa90a56e753c6e93c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 492 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 literal 0 HcmV?d00001 diff --git a/shadowsocks-csharp/Resources/ss32Fill.png b/shadowsocks-csharp/Resources/ss32Fill.png new file mode 100644 index 0000000000000000000000000000000000000000..5b603bb342b0b0353d2bf9a542338f7c45f47e19 GIT binary patch literal 617 zcmV-v0+#)WP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BK;VQFr3E^cLXAT%y9E;jv63FrU-0oqAKK~z{r?UcVu!%!53vxtiz(#b^%ii?9N z*ulw35OEL}L0sG&T%4p`oTQ83EG`b>;Glm)Hy1@*1YKR+4D?5;Uz!tbOq;yaG)3@( zOY-i$=bqQRq}D%!pxJB|9LK3}-BBtVeB%#c+xCP?{ROX4%uhXA57sX#_YZtR#y;fF z)s{ZY?`rHreN*k}!Q5D5pH$DEdB(;r^xBgC4rWCfQ+wvEf6(#^^4A*C8_X~{<9nj4 zWq?Mbv8z$ZKx_1<>AB#tjM4mtOUW^|lcg=5=?nEo4As`1?z&!Zhb~+ zBj{g{G&#Jz`wVEk={~IQG}{Qt(gE{j;z_e(p*Q~gdx60@Vv7hI)laA&NRkfB9MNq6 zj8>_IzNmV=zM__N!03>8Bleg-rgQ-EdFo}tCWe(x2L_f}KMlBlS2{b|H^6_voYL9h zZ-BqxW2Lf%4HSu2_AsPWwqSlVkVo&s2BviTm$9r*`EyvFhvJSC00000NkvXXu0mjf Dx-uPE literal 0 HcmV?d00001 diff --git a/shadowsocks-csharp/Resources/ss32In.png b/shadowsocks-csharp/Resources/ss32In.png new file mode 100644 index 0000000000000000000000000000000000000000..d3e0aa911f56ed233f94c8e06560cd58e0376c08 GIT binary patch literal 211 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;>1s;*b3=DjSL74G){)!Z!phSslL`iUdT1k0gQ7S`0VrE{6US4X6f{C7? zp4neN&KE#6E}kxqArbCx&lz$tDDXI6l)1XN%GfnST+`yH-han!4oW~Z3>oI_*R%t_ xu3&rba&@`XS(l@$rOvq=U0-UmwNL&(zlU@OZ?u{G`?vNWwVtkiF6*2UngG{FKtlik literal 0 HcmV?d00001 diff --git a/shadowsocks-csharp/Resources/ss32Out.png b/shadowsocks-csharp/Resources/ss32Out.png new file mode 100644 index 0000000000000000000000000000000000000000..6f6b4cb82ae178985e5901cdaa9421d6cec83e76 GIT binary patch literal 215 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;>1s;*b3=DjSL74G){)!Z!phSslL`iUdT1k0gQ7S`0VrE{6US4X6f{C7? zp4neN&KE#69-c0aArbCx&mH7sFyL?wbbqUH_fDKrN5$6GPx4Qc8Z&O*dM7ydUDYoK zx&8lK%;f@8!^~v@Q~k`N7QgDr+u#-oG=t&C#G8!AYpcCY>gA?__@1tQF6*2UngG|u BM3n#l literal 0 HcmV?d00001 diff --git a/shadowsocks-csharp/Resources/ss32Outline.png b/shadowsocks-csharp/Resources/ss32Outline.png new file mode 100644 index 0000000000000000000000000000000000000000..2407fb7c238cbdddf44c4e2673c2acd7501264e2 GIT binary patch literal 787 zcmV+u1MK{XP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BK;VQFr3E^cLXAT%y9E;jv63FrU-0)$CKK~z{r#gkPt^_&0g#BJTJQ{>Gd56}!fM{DpUL8t%rs*m1Vw zPke-Pe34=V4uoN6Scl*7B`)$s1D|k47{+APJayoY(U+?Tm%-M>ehPOBXn#lvCP8guK8pQ5!~#wPrRSI|Q_0$X7Umxf_8 z_G>48jn;CNJY7V0z8Ae@reYC4u<77##kZ-B?Nn8Gj{eOObn=y0#6mPub=a}YvmdyR ztJ8NySXzeqAx=WWTIFInhF(HVIH7slgU`@Y`~Wv#<6_)}Vf2(6DSN^#tb!5S8HUBU zm~Cjsaxu1A|B>);y7OJ=`8bG1uWHH+e_1s(;m4Qb4fI~ms=}W(lnKdGIsTr9bzJh) zPqK@~v{)@J$nY<~vWnS((QZH)izD$U+Wm~iC7g|UTt^#Q6taIPPT>$=fVF)By`(&( z=Wse^_HTo9u0%P@boYV~EG`x04+C8VopC%BAH) z>X+zi+iTe$ntZHzlG>#s%+(Ja4(V{47@r9_n4+q{$m!w0q;zEMKJ)19|MNF6e8~A^ ze4tz74O?{Wou)aoab=(Cqp5 QK`vzQboFyt=akR{0G??{xBvhE diff --git a/shadowsocks-csharp/Resources/ssOut24.png b/shadowsocks-csharp/Resources/ssOut24.png deleted file mode 100644 index 4768ac8731baeeec083eed6fac5f60f86f041ec0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 239 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjY)RhkE(`}45*QdF8fUZsMK}vQ zB8wRq_zr< g;Yj?)|K>Xwmb9v^a*COd26P95r>mdKI;Vst0AZ6;5C8xG diff --git a/shadowsocks-csharp/Util/Util.cs b/shadowsocks-csharp/Util/Util.cs index b62bb567..47b1a0b7 100755 --- a/shadowsocks-csharp/Util/Util.cs +++ b/shadowsocks-csharp/Util/Util.cs @@ -60,18 +60,16 @@ namespace Shadowsocks.Util // Support on Windows 10 1903+ public static WindowsThemeMode GetWindows10SystemThemeSetting() { - WindowsThemeMode registData = WindowsThemeMode.Dark; + WindowsThemeMode themeMode = WindowsThemeMode.Dark; try { - RegistryKey reg_HKCU = Registry.CurrentUser; - RegistryKey reg_ThemesPersonalize = reg_HKCU.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize", false); + RegistryKey reg_ThemesPersonalize = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize", false); if (reg_ThemesPersonalize.GetValue("SystemUsesLightTheme") != null) { - if (Convert.ToInt32(reg_ThemesPersonalize.GetValue("SystemUsesLightTheme").ToString()) == 0) // 0:dark mode, 1:light mode - registData = WindowsThemeMode.Dark; + if ((int)(reg_ThemesPersonalize.GetValue("SystemUsesLightTheme")) == 0) // 0:dark mode, 1:light mode + themeMode = WindowsThemeMode.Dark; else - registData = WindowsThemeMode.Light; - //Console.WriteLine(registData); + themeMode = WindowsThemeMode.Light; } else { @@ -83,7 +81,7 @@ namespace Shadowsocks.Util Logging.Info( $"Cannot get Windows 10 system theme mode, return default value 0 (dark mode)."); } - return registData; + return themeMode; } // return a full path with filename combined which pointed to the temporary directory diff --git a/shadowsocks-csharp/Util/ViewUtils.cs b/shadowsocks-csharp/Util/ViewUtils.cs index 7131d40d..fab38037 100644 --- a/shadowsocks-csharp/Util/ViewUtils.cs +++ b/shadowsocks-csharp/Util/ViewUtils.cs @@ -1,35 +1,99 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Windows.Forms; - -namespace Shadowsocks.Util -{ - public static class ViewUtils - { - public static IEnumerable GetChildControls(this Control control) where TControl : Control - { - if (control.Controls.Count == 0) - { - return Enumerable.Empty(); - } - - var children = control.Controls.OfType().ToList(); - return children.SelectMany(GetChildControls).Concat(children); - } - - // Workaround NotifyIcon's 63 chars limit - // https://stackoverflow.com/questions/579665/how-can-i-show-a-systray-tooltip-longer-than-63-chars - public static void SetNotifyIconText(NotifyIcon ni, string text) - { - if (text.Length >= 128) - throw new ArgumentOutOfRangeException("Text limited to 127 characters"); - Type t = typeof(NotifyIcon); - BindingFlags hidden = BindingFlags.NonPublic | BindingFlags.Instance; - t.GetField("text", hidden).SetValue(ni, text); - if ((bool)t.GetField("added", hidden).GetValue(ni)) - t.GetMethod("UpdateIcon", hidden).Invoke(ni, new object[] { true }); - } - } -} +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Imaging; +using System.Linq; +using System.Reflection; +using System.Windows.Forms; + +namespace Shadowsocks.Util +{ + public static class ViewUtils + { + public static IEnumerable GetChildControls(this Control control) where TControl : Control + { + if (control.Controls.Count == 0) + { + return Enumerable.Empty(); + } + + var children = control.Controls.OfType().ToList(); + return children.SelectMany(GetChildControls).Concat(children); + } + + // Workaround NotifyIcon's 63 chars limit + // https://stackoverflow.com/questions/579665/how-can-i-show-a-systray-tooltip-longer-than-63-chars + public static void SetNotifyIconText(NotifyIcon ni, string text) + { + if (text.Length >= 128) + throw new ArgumentOutOfRangeException("Text limited to 127 characters"); + Type t = typeof(NotifyIcon); + BindingFlags hidden = BindingFlags.NonPublic | BindingFlags.Instance; + t.GetField("text", hidden).SetValue(ni, text); + if ((bool)t.GetField("added", hidden).GetValue(ni)) + t.GetMethod("UpdateIcon", hidden).Invoke(ni, new object[] { true }); + } + + public static Bitmap AddBitmapOverlay(Bitmap original, params Bitmap[] overlays) + { + Bitmap bitmap = new Bitmap(original.Width, original.Height, PixelFormat.Format64bppArgb); + Graphics canvas = Graphics.FromImage(bitmap); + canvas.DrawImage(original, new Point(0, 0)); + foreach (Bitmap overlay in overlays) + { + canvas.DrawImage(new Bitmap(overlay, original.Size), new Point(0, 0)); + } + canvas.Save(); + return bitmap; + } + + public static Bitmap ChangeBitmapColor(Bitmap original, Color colorMask) + { + Bitmap newBitmap = new Bitmap(original); + + for (int x = 0; x < newBitmap.Width; x++) + { + for (int y = 0; y < newBitmap.Height; y++) + { + Color color = original.GetPixel(x, y); + if (color.A != 0) + { + int red = color.R * colorMask.R / 255; + int green = color.G * colorMask.G / 255; + int blue = color.B * colorMask.B / 255; + int alpha = color.A * colorMask.A / 255; + newBitmap.SetPixel(x, y, Color.FromArgb(alpha, red, green, blue)); + } + else + { + newBitmap.SetPixel(x, y, color); + } + } + } + return newBitmap; + } + + public static Bitmap ResizeBitmap (Bitmap original, int width, int height) + { + Bitmap newBitmap = new Bitmap(width, height); + using (Graphics g = Graphics.FromImage(newBitmap)) + { + g.SmoothingMode = SmoothingMode.HighQuality; + g.InterpolationMode = InterpolationMode.HighQualityBicubic; + g.PixelOffsetMode = PixelOffsetMode.HighQuality; + g.CompositingQuality = CompositingQuality.HighQuality; + g.DrawImage(original, new Rectangle(0, 0, width, height)); + } + return newBitmap; + } + + public static int GetScreenDpi() + { + Graphics graphics = Graphics.FromHwnd(IntPtr.Zero); + int dpi = (int)graphics.DpiX; + graphics.Dispose(); + return dpi; + } + } +} diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs index b593fefb..a1d2ef4f 100644 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ b/shadowsocks-csharp/View/MenuViewController.cs @@ -28,12 +28,13 @@ namespace Shadowsocks.View private UpdateChecker updateChecker; private NotifyIcon _notifyIcon; - private Bitmap icon_baseBitmap; - private Icon icon_base, icon_in, icon_out, icon_both, targetIcon; - private ContextMenu contextMenu1; + private Icon icon, icon_in, icon_out, icon_both, previousIcon; private bool _isFirstRun; private bool _isStartupChecking; + private string _urlToOpen; + + private ContextMenu contextMenu1; private MenuItem disableItem; private MenuItem AutoStartupItem; private MenuItem ShareOverLANItem; @@ -54,12 +55,19 @@ namespace Shadowsocks.View private MenuItem proxyItem; private MenuItem hotKeyItem; private MenuItem VerboseLoggingToggleItem; + private ConfigForm configForm; private ProxyForm proxyForm; private LogForm logForm; private HotkeySettingsForm hotkeySettingsForm; - private string _urlToOpen; - private Utils.WindowsThemeMode currentWindowsThemeMode; + + + + // color definition for icon color transformation + private readonly Color colorMaskBlue = Color.FromArgb(255, 25, 125, 191); + private readonly Color colorMaskDarkSilver = Color.FromArgb(128, 192, 192, 192); + private readonly Color colorMaskLightSilver = Color.FromArgb(192, 192, 192, 192); + private readonly Color colorMaskEclipse = Color.FromArgb(192, 64, 64, 64); public MenuViewController(ShadowsocksController controller) { @@ -79,7 +87,7 @@ namespace Shadowsocks.View controller.UpdatePACFromGFWListError += controller_UpdatePACFromGFWListError; _notifyIcon = new NotifyIcon(); - UpdateTrayIcon(); + UpdateTrayIconAndNotifyText(); _notifyIcon.Visible = true; _notifyIcon.ContextMenu = contextMenu1; _notifyIcon.BalloonTipClicked += notifyIcon1_BalloonTipClicked; @@ -109,7 +117,7 @@ namespace Shadowsocks.View private void controller_TrafficChanged(object sender, EventArgs e) { - if (icon_baseBitmap == null) + if (icon == null) return; Icon newIcon; @@ -124,11 +132,11 @@ namespace Shadowsocks.View else if (hasOutbound) newIcon = icon_out; else - newIcon = icon_base; + newIcon = icon; - if (newIcon != this.targetIcon) + if (newIcon != this.previousIcon) { - this.targetIcon = newIcon; + this.previousIcon = newIcon; _notifyIcon.Icon = newIcon; } } @@ -140,46 +148,19 @@ namespace Shadowsocks.View #region Tray Icon - private void UpdateTrayIcon() + private void UpdateTrayIconAndNotifyText() { - int dpi; - Graphics graphics = Graphics.FromHwnd(IntPtr.Zero); - dpi = (int)graphics.DpiX; - graphics.Dispose(); - icon_baseBitmap = null; - if (dpi < 97) - { - // dpi = 96; - icon_baseBitmap = Resources.ss16; - } - else if (dpi < 121) - { - // dpi = 120; - icon_baseBitmap = Resources.ss20; - } - else - { - icon_baseBitmap = Resources.ss24; - } Configuration config = controller.GetConfigurationCopy(); bool enabled = config.enabled; bool global = config.global; - // set Windows 10 Theme color (1903+) - currentWindowsThemeMode = Utils.GetWindows10SystemThemeSetting(); + Color colorMask = SelectColorMask(enabled, global); + Size iconSize = SelectIconSize(); - if (currentWindowsThemeMode == Utils.WindowsThemeMode.Light) - if (!global || !enabled) - icon_baseBitmap = getDarkTrayIcon(icon_baseBitmap); + UpdateIconSet(colorMask, iconSize, out icon, out icon_in, out icon_out, out icon_both); - icon_baseBitmap = getTrayIconByState(icon_baseBitmap, enabled, global); - - icon_base = Icon.FromHandle(icon_baseBitmap.GetHicon()); - targetIcon = icon_base; - icon_in = Icon.FromHandle(AddBitmapOverlay(icon_baseBitmap, Resources.ssIn24).GetHicon()); - icon_out = Icon.FromHandle(AddBitmapOverlay(icon_baseBitmap, Resources.ssOut24).GetHicon()); - icon_both = Icon.FromHandle(AddBitmapOverlay(icon_baseBitmap, Resources.ssIn24, Resources.ssOut24).GetHicon()); - _notifyIcon.Icon = targetIcon; + previousIcon = icon; + _notifyIcon.Icon = previousIcon; string serverInfo = null; if (controller.GetCurrentStrategy() != null) @@ -203,89 +184,90 @@ namespace Shadowsocks.View ViewUtils.SetNotifyIconText(_notifyIcon, text); } - private Bitmap getDarkTrayIcon(Bitmap originIcon) + /// + /// Determine the icon size based on the screen DPI. + /// + /// + /// https://stackoverflow.com/a/40851713/2075611 + private Size SelectIconSize() { - Bitmap iconCopy = new Bitmap(originIcon); - for (int x = 0; x < iconCopy.Width; x++) + Size size = new Size(32, 32); + int dpi = ViewUtils.GetScreenDpi(); + if (dpi < 97) { - for (int y = 0; y < iconCopy.Height; y++) - { - Color color = originIcon.GetPixel(x, y); - if (color.A != 0) - { - Color flyBlue = Color.FromArgb(192, 0, 0, 0); - // Multiply with flyBlue - int red = color.R * flyBlue.R / 255; - int green = color.G * flyBlue.G / 255; - int blue = color.B * flyBlue.B / 255; - int alpha = color.A; - iconCopy.SetPixel(x, y, Color.FromArgb(alpha, red, green, blue)); - } - else - { - iconCopy.SetPixel(x, y, Color.FromArgb(color.A, color.R, color.G, color.B)); - } - } + // dpi = 96; + size = new Size(16, 16); + } + else if (dpi < 121) + { + // dpi = 120; + size = new Size(20, 20); + } + else if (dpi < 145) + { + // dpi = 144; + size = new Size(24, 24); } - return iconCopy; + else + { + // dpi = 168; + size = new Size(28, 28); + } + return size; } - private Bitmap getTrayIconByState(Bitmap originIcon, bool enabled, bool global) + private Color SelectColorMask(bool isProxyEnabled, bool isGlobalProxy) { - Bitmap iconCopy = new Bitmap(originIcon); - for (int x = 0; x < iconCopy.Width; x++) + Color colorMask = Color.White; + + Utils.WindowsThemeMode currentWindowsThemeMode = Utils.GetWindows10SystemThemeSetting(); + + if (isProxyEnabled) { - for (int y = 0; y < iconCopy.Height; y++) + if (isGlobalProxy) // global { - Color color = originIcon.GetPixel(x, y); - if (color.A != 0) - { - if (!enabled) - { - // Multiply with flyBlue - Color flyBlue; - if (currentWindowsThemeMode == Utils.WindowsThemeMode.Light) - flyBlue = Color.FromArgb(128, 192, 192, 192); // Dark icon more transparent - else - flyBlue = Color.FromArgb(192, 192, 192, 192); // Light icon less transparent - int red = color.R * flyBlue.R / 255; - int green = color.G * flyBlue.G / 255; - int blue = color.B * flyBlue.B / 255; - int alpha = color.A * flyBlue.A / 255; - iconCopy.SetPixel(x, y, Color.FromArgb(alpha, red, green, blue)); - } - else if (global) - { - Color flyBlue = Color.FromArgb(25, 125, 191); - // Multiply with flyBlue - int red = color.R * flyBlue.R / 255; - int green = color.G * flyBlue.G / 255; - int blue = color.B * flyBlue.B / 255; - iconCopy.SetPixel(x, y, Color.FromArgb(color.A, red, green, blue)); - } - } - else + colorMask = colorMaskBlue; + } + else // PAC + { + if (currentWindowsThemeMode == Utils.WindowsThemeMode.Light) { - iconCopy.SetPixel(x, y, Color.FromArgb(color.A, color.R, color.G, color.B)); + colorMask = colorMaskEclipse; } } } - return iconCopy; + else // disabled + { + if (currentWindowsThemeMode == Utils.WindowsThemeMode.Light) + { + colorMask = colorMaskDarkSilver; + } + else + { + colorMask = colorMaskLightSilver; + } + } + + return colorMask; } - private Bitmap AddBitmapOverlay(Bitmap original, params Bitmap[] overlays) + private void UpdateIconSet(Color colorMask, Size size, + out Icon icon, out Icon icon_in, out Icon icon_out, out Icon icon_both) { - Bitmap bitmap = new Bitmap(original.Width, original.Height, PixelFormat.Format64bppArgb); - Graphics canvas = Graphics.FromImage(bitmap); - canvas.DrawImage(original, new Point(0, 0)); - foreach (Bitmap overlay in overlays) - { - canvas.DrawImage(new Bitmap(overlay, original.Size), new Point(0, 0)); - } - canvas.Save(); - return bitmap; + Bitmap iconBitmap; + + // generate the base icon + iconBitmap = ViewUtils.ChangeBitmapColor(Resources.ss32Fill, colorMask); + iconBitmap = ViewUtils.AddBitmapOverlay(iconBitmap, Resources.ss32Outline); + + icon = Icon.FromHandle(ViewUtils.ResizeBitmap(iconBitmap, size.Width, size.Height).GetHicon()); + icon_in = Icon.FromHandle(ViewUtils.ResizeBitmap(ViewUtils.AddBitmapOverlay(iconBitmap, Resources.ss32In), size.Width, size.Height).GetHicon()); + icon_out = Icon.FromHandle(ViewUtils.ResizeBitmap(ViewUtils.AddBitmapOverlay(iconBitmap, Resources.ss32In), size.Width, size.Height).GetHicon()); + icon_both = Icon.FromHandle(ViewUtils.ResizeBitmap(ViewUtils.AddBitmapOverlay(iconBitmap, Resources.ss32In, Resources.ss32Out), size.Width, size.Height).GetHicon()); } + + #endregion #region MenuItems and MenuGroups @@ -355,7 +337,7 @@ namespace Shadowsocks.View private void controller_ConfigChanged(object sender, EventArgs e) { LoadCurrentConfiguration(); - UpdateTrayIcon(); + UpdateTrayIconAndNotifyText(); } private void controller_EnableStatusChanged(object sender, EventArgs e) @@ -629,7 +611,7 @@ namespace Shadowsocks.View private void notifyIcon1_Click(object sender, MouseEventArgs e) { - UpdateTrayIcon(); + UpdateTrayIconAndNotifyText(); if (e.Button == MouseButtons.Middle) { ShowLogForm(); diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj index 68c76381..40e59bf3 100644 --- a/shadowsocks-csharp/shadowsocks-csharp.csproj +++ b/shadowsocks-csharp/shadowsocks-csharp.csproj @@ -124,6 +124,11 @@ + + True + True + Resources.resx + True True @@ -150,11 +155,6 @@ - - True - True - Resources.resx - @@ -269,9 +269,6 @@ SettingsSingleFileGenerator Settings.Designer.cs - - - @@ -281,8 +278,10 @@ Designer - - + + + +