@@ -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 { | |||
/// <summary> | |||
/// Looks up a localized resource of type System.Drawing.Bitmap. | |||
/// </summary> | |||
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 { | |||
/// <summary> | |||
/// Looks up a localized resource of type System.Drawing.Bitmap. | |||
/// </summary> | |||
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 { | |||
/// <summary> | |||
/// Looks up a localized resource of type System.Drawing.Bitmap. | |||
/// </summary> | |||
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 { | |||
/// <summary> | |||
/// Looks up a localized resource of type System.Drawing.Bitmap. | |||
/// </summary> | |||
internal static System.Drawing.Bitmap ssIn24 { | |||
internal static System.Drawing.Bitmap ss32Outline { | |||
get { | |||
object obj = ResourceManager.GetObject("ssIn24", resourceCulture); | |||
return ((System.Drawing.Bitmap)(obj)); | |||
} | |||
} | |||
/// <summary> | |||
/// Looks up a localized resource of type System.Drawing.Bitmap. | |||
/// </summary> | |||
internal static System.Drawing.Bitmap ssOut24 { | |||
get { | |||
object obj = ResourceManager.GetObject("ssOut24", resourceCulture); | |||
object obj = ResourceManager.GetObject("ss32Outline", resourceCulture); | |||
return ((System.Drawing.Bitmap)(obj)); | |||
} | |||
} | |||
@@ -136,20 +136,17 @@ | |||
<data name="proxy_pac_txt" type="System.Resources.ResXFileRef, System.Windows.Forms"> | |||
<value>..\Data\proxy.pac.txt.gz;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||
</data> | |||
<data name="ss16" type="System.Resources.ResXFileRef, System.Windows.Forms"> | |||
<value>..\Resources\ss16.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> | |||
<data name="ss32Fill" type="System.Resources.ResXFileRef, System.Windows.Forms"> | |||
<value>..\Resources\ss32Fill.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> | |||
</data> | |||
<data name="ss20" type="System.Resources.ResXFileRef, System.Windows.Forms"> | |||
<value>..\Resources\ss20.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> | |||
<data name="ss32In" type="System.Resources.ResXFileRef, System.Windows.Forms"> | |||
<value>..\Resources\ss32In.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> | |||
</data> | |||
<data name="ss24" type="System.Resources.ResXFileRef, System.Windows.Forms"> | |||
<value>..\Resources\ss24.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> | |||
<data name="ss32Out" type="System.Resources.ResXFileRef, System.Windows.Forms"> | |||
<value>..\Resources\ss32Out.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> | |||
</data> | |||
<data name="ssIn24" type="System.Resources.ResXFileRef, System.Windows.Forms"> | |||
<value>..\Resources\ssIn24.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> | |||
</data> | |||
<data name="ssOut24" type="System.Resources.ResXFileRef, System.Windows.Forms"> | |||
<value>..\Resources\ssOut24.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> | |||
<data name="ss32Outline" type="System.Resources.ResXFileRef, System.Windows.Forms"> | |||
<value>..\Resources\ss32Outline.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> | |||
</data> | |||
<data name="ssw128" type="System.Resources.ResXFileRef, System.Windows.Forms"> | |||
<value>..\Resources\ssw128.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> | |||
@@ -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 | |||
@@ -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<TControl> GetChildControls<TControl>(this Control control) where TControl : Control | |||
{ | |||
if (control.Controls.Count == 0) | |||
{ | |||
return Enumerable.Empty<TControl>(); | |||
} | |||
var children = control.Controls.OfType<TControl>().ToList(); | |||
return children.SelectMany(GetChildControls<TControl>).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<TControl> GetChildControls<TControl>(this Control control) where TControl : Control | |||
{ | |||
if (control.Controls.Count == 0) | |||
{ | |||
return Enumerable.Empty<TControl>(); | |||
} | |||
var children = control.Controls.OfType<TControl>().ToList(); | |||
return children.SelectMany(GetChildControls<TControl>).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; | |||
} | |||
} | |||
} |
@@ -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) | |||
/// <summary> | |||
/// Determine the icon size based on the screen DPI. | |||
/// </summary> | |||
/// <returns></returns> | |||
/// 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(); | |||
@@ -124,6 +124,11 @@ | |||
<Compile Include="Model\HotKeyConfig.cs" /> | |||
<Compile Include="Model\ProxyConfig.cs" /> | |||
<Compile Include="Model\SysproxyConfig.cs" /> | |||
<Compile Include="Properties\Resources.Designer.cs"> | |||
<AutoGen>True</AutoGen> | |||
<DesignTime>True</DesignTime> | |||
<DependentUpon>Resources.resx</DependentUpon> | |||
</Compile> | |||
<Compile Include="Properties\Settings.Designer.cs"> | |||
<AutoGen>True</AutoGen> | |||
<DesignTimeSharedInput>True</DesignTimeSharedInput> | |||
@@ -150,11 +155,6 @@ | |||
<Compile Include="Model\Configuration.cs" /> | |||
<Compile Include="Model\StatisticsRecord.cs" /> | |||
<Compile Include="Model\StatisticsStrategyConfiguration.cs" /> | |||
<Compile Include="Properties\Resources.Designer.cs"> | |||
<AutoGen>True</AutoGen> | |||
<DesignTime>True</DesignTime> | |||
<DependentUpon>Resources.resx</DependentUpon> | |||
</Compile> | |||
<Compile Include="Controller\Strategy\BalancingStrategy.cs" /> | |||
<Compile Include="Controller\Strategy\StrategyManager.cs" /> | |||
<Compile Include="Controller\Strategy\IStrategy.cs" /> | |||
@@ -269,9 +269,6 @@ | |||
<Generator>SettingsSingleFileGenerator</Generator> | |||
<LastGenOutput>Settings.Designer.cs</LastGenOutput> | |||
</None> | |||
<None Include="Resources\ss20.png" /> | |||
<None Include="Resources\ss16.png" /> | |||
<None Include="Resources\ss24.png" /> | |||
<None Include="Resources\ssw128.png" /> | |||
<Content Include="Data\zh_CN.txt" /> | |||
<Content Include="Data\zh_TW.txt" /> | |||
@@ -281,8 +278,10 @@ | |||
<None Include="FodyWeavers.xml"> | |||
<SubType>Designer</SubType> | |||
</None> | |||
<Content Include="Resources\ssIn24.png" /> | |||
<Content Include="Resources\ssOut24.png" /> | |||
<Content Include="Resources\ss32Fill.png" /> | |||
<Content Include="Resources\ss32In.png" /> | |||
<Content Include="Resources\ss32Out.png" /> | |||
<Content Include="Resources\ss32Outline.png" /> | |||
<Content Include="shadowsocks.ico" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||