@@ -39,8 +39,8 @@ namespace Shadowsocks | |||||
Application.SetCompatibleTextRenderingDefault(false); | Application.SetCompatibleTextRenderingDefault(false); | ||||
ShadowsocksController controller = new ShadowsocksController(); | ShadowsocksController controller = new ShadowsocksController(); | ||||
// TODO run without a main form to save RAM | |||||
Application.Run(new ConfigForm(controller)); | |||||
MenuViewController viewController = new MenuViewController(controller); | |||||
Application.Run(); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -28,7 +28,6 @@ | |||||
/// </summary> | /// </summary> | ||||
private void InitializeComponent() | private void InitializeComponent() | ||||
{ | { | ||||
this.components = new System.ComponentModel.Container(); | |||||
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); | this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); | ||||
this.RemarksTextBox = new System.Windows.Forms.TextBox(); | this.RemarksTextBox = new System.Windows.Forms.TextBox(); | ||||
this.label6 = new System.Windows.Forms.Label(); | this.label6 = new System.Windows.Forms.Label(); | ||||
@@ -42,31 +41,15 @@ | |||||
this.PasswordTextBox = new System.Windows.Forms.TextBox(); | this.PasswordTextBox = new System.Windows.Forms.TextBox(); | ||||
this.label5 = new System.Windows.Forms.Label(); | this.label5 = new System.Windows.Forms.Label(); | ||||
this.EncryptionSelect = new System.Windows.Forms.ComboBox(); | this.EncryptionSelect = new System.Windows.Forms.ComboBox(); | ||||
this.notifyIcon1 = new System.Windows.Forms.NotifyIcon(this.components); | |||||
this.panel2 = new System.Windows.Forms.Panel(); | this.panel2 = new System.Windows.Forms.Panel(); | ||||
this.OKButton = new System.Windows.Forms.Button(); | this.OKButton = new System.Windows.Forms.Button(); | ||||
this.MyCancelButton = new System.Windows.Forms.Button(); | this.MyCancelButton = new System.Windows.Forms.Button(); | ||||
this.panel1 = new System.Windows.Forms.Panel(); | this.panel1 = new System.Windows.Forms.Panel(); | ||||
this.contextMenu1 = new System.Windows.Forms.ContextMenu(); | |||||
this.enableItem = new System.Windows.Forms.MenuItem(); | |||||
this.AutoStartupItem = new System.Windows.Forms.MenuItem(); | |||||
this.ShareOverLANItem = new System.Windows.Forms.MenuItem(); | |||||
this.ServersItem = new System.Windows.Forms.MenuItem(); | |||||
this.SeperatorItem = new System.Windows.Forms.MenuItem(); | |||||
this.ConfigItem = new System.Windows.Forms.MenuItem(); | |||||
this.menuItem4 = new System.Windows.Forms.MenuItem(); | |||||
this.editPACFileItem = new System.Windows.Forms.MenuItem(); | |||||
this.QRCodeItem = new System.Windows.Forms.MenuItem(); | |||||
this.ShowLogItem = new System.Windows.Forms.MenuItem(); | |||||
this.aboutItem = new System.Windows.Forms.MenuItem(); | |||||
this.menuItem3 = new System.Windows.Forms.MenuItem(); | |||||
this.quitItem = new System.Windows.Forms.MenuItem(); | |||||
this.panel3 = new System.Windows.Forms.Panel(); | this.panel3 = new System.Windows.Forms.Panel(); | ||||
this.DeleteButton = new System.Windows.Forms.Button(); | this.DeleteButton = new System.Windows.Forms.Button(); | ||||
this.AddButton = new System.Windows.Forms.Button(); | this.AddButton = new System.Windows.Forms.Button(); | ||||
this.ServerGroupBox = new System.Windows.Forms.GroupBox(); | this.ServerGroupBox = new System.Windows.Forms.GroupBox(); | ||||
this.ServersListBox = new System.Windows.Forms.ListBox(); | this.ServersListBox = new System.Windows.Forms.ListBox(); | ||||
this.menuItem1 = new System.Windows.Forms.MenuItem(); | |||||
this.tableLayoutPanel1.SuspendLayout(); | this.tableLayoutPanel1.SuspendLayout(); | ||||
this.panel1.SuspendLayout(); | this.panel1.SuspendLayout(); | ||||
this.panel3.SuspendLayout(); | this.panel3.SuspendLayout(); | ||||
@@ -93,9 +76,9 @@ | |||||
this.tableLayoutPanel1.Controls.Add(this.label5, 0, 3); | this.tableLayoutPanel1.Controls.Add(this.label5, 0, 3); | ||||
this.tableLayoutPanel1.Controls.Add(this.EncryptionSelect, 1, 3); | this.tableLayoutPanel1.Controls.Add(this.EncryptionSelect, 1, 3); | ||||
this.tableLayoutPanel1.Location = new System.Drawing.Point(8, 21); | this.tableLayoutPanel1.Location = new System.Drawing.Point(8, 21); | ||||
this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5); | |||||
this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(5); | |||||
this.tableLayoutPanel1.Name = "tableLayoutPanel1"; | this.tableLayoutPanel1.Name = "tableLayoutPanel1"; | ||||
this.tableLayoutPanel1.Padding = new System.Windows.Forms.Padding(5, 5, 5, 5); | |||||
this.tableLayoutPanel1.Padding = new System.Windows.Forms.Padding(5); | |||||
this.tableLayoutPanel1.RowCount = 6; | this.tableLayoutPanel1.RowCount = 6; | ||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); | this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); | ||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); | this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); | ||||
@@ -233,11 +216,6 @@ | |||||
this.EncryptionSelect.Size = new System.Drawing.Size(160, 21); | this.EncryptionSelect.Size = new System.Drawing.Size(160, 21); | ||||
this.EncryptionSelect.TabIndex = 3; | this.EncryptionSelect.TabIndex = 3; | ||||
// | // | ||||
// notifyIcon1 | |||||
// | |||||
this.notifyIcon1.Text = "Shadowsocks"; | |||||
this.notifyIcon1.DoubleClick += new System.EventHandler(this.notifyIcon1_DoubleClick); | |||||
// | |||||
// panel2 | // panel2 | ||||
// | // | ||||
this.panel2.Anchor = System.Windows.Forms.AnchorStyles.Top; | this.panel2.Anchor = System.Windows.Forms.AnchorStyles.Top; | ||||
@@ -282,99 +260,6 @@ | |||||
this.panel1.Size = new System.Drawing.Size(165, 30); | this.panel1.Size = new System.Drawing.Size(165, 30); | ||||
this.panel1.TabIndex = 1; | this.panel1.TabIndex = 1; | ||||
// | // | ||||
// contextMenu1 | |||||
// | |||||
this.contextMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { | |||||
this.enableItem, | |||||
this.ServersItem, | |||||
this.menuItem1, | |||||
this.AutoStartupItem, | |||||
this.ShareOverLANItem, | |||||
this.editPACFileItem, | |||||
this.menuItem4, | |||||
this.QRCodeItem, | |||||
this.ShowLogItem, | |||||
this.aboutItem, | |||||
this.menuItem3, | |||||
this.quitItem}); | |||||
// | |||||
// enableItem | |||||
// | |||||
this.enableItem.Index = 0; | |||||
this.enableItem.Text = "&Enable"; | |||||
this.enableItem.Click += new System.EventHandler(this.EnableItem_Click); | |||||
// | |||||
// AutoStartupItem | |||||
// | |||||
this.AutoStartupItem.Index = 3; | |||||
this.AutoStartupItem.Text = "Start on Boot"; | |||||
this.AutoStartupItem.Click += new System.EventHandler(this.AutoStartupItem_Click); | |||||
// | |||||
// ShareOverLANItem | |||||
// | |||||
this.ShareOverLANItem.Index = 4; | |||||
this.ShareOverLANItem.Text = "Share over LAN"; | |||||
this.ShareOverLANItem.Click += new System.EventHandler(this.ShareOverLANItem_Click); | |||||
// | |||||
// ServersItem | |||||
// | |||||
this.ServersItem.Index = 1; | |||||
this.ServersItem.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { | |||||
this.SeperatorItem, | |||||
this.ConfigItem}); | |||||
this.ServersItem.Text = "&Servers"; | |||||
// | |||||
// SeperatorItem | |||||
// | |||||
this.SeperatorItem.Index = 0; | |||||
this.SeperatorItem.Text = "-"; | |||||
// | |||||
// ConfigItem | |||||
// | |||||
this.ConfigItem.Index = 1; | |||||
this.ConfigItem.Text = "Edit Servers..."; | |||||
this.ConfigItem.Click += new System.EventHandler(this.Config_Click); | |||||
// | |||||
// menuItem4 | |||||
// | |||||
this.menuItem4.Index = 6; | |||||
this.menuItem4.Text = "-"; | |||||
// | |||||
// editPACFileItem | |||||
// | |||||
this.editPACFileItem.Index = 5; | |||||
this.editPACFileItem.Text = "Edit &PAC File..."; | |||||
this.editPACFileItem.Click += new System.EventHandler(this.EditPACFileItem_Click); | |||||
// | |||||
// QRCodeItem | |||||
// | |||||
this.QRCodeItem.Index = 7; | |||||
this.QRCodeItem.Text = "Show &QRCode..."; | |||||
this.QRCodeItem.Click += new System.EventHandler(this.QRCodeItem_Click); | |||||
// | |||||
// ShowLogItem | |||||
// | |||||
this.ShowLogItem.Index = 8; | |||||
this.ShowLogItem.Text = "Show Logs..."; | |||||
this.ShowLogItem.Click += new System.EventHandler(this.ShowLogItem_Click); | |||||
// | |||||
// aboutItem | |||||
// | |||||
this.aboutItem.Index = 9; | |||||
this.aboutItem.Text = "About..."; | |||||
this.aboutItem.Click += new System.EventHandler(this.AboutItem_Click); | |||||
// | |||||
// menuItem3 | |||||
// | |||||
this.menuItem3.Index = 10; | |||||
this.menuItem3.Text = "-"; | |||||
// | |||||
// quitItem | |||||
// | |||||
this.quitItem.Index = 11; | |||||
this.quitItem.Text = "&Quit"; | |||||
this.quitItem.Click += new System.EventHandler(this.Quit_Click); | |||||
// | |||||
// panel3 | // panel3 | ||||
// | // | ||||
this.panel3.AutoSize = true; | this.panel3.AutoSize = true; | ||||
@@ -425,11 +310,6 @@ | |||||
this.ServersListBox.TabIndex = 5; | this.ServersListBox.TabIndex = 5; | ||||
this.ServersListBox.SelectedIndexChanged += new System.EventHandler(this.ServersListBox_SelectedIndexChanged); | this.ServersListBox.SelectedIndexChanged += new System.EventHandler(this.ServersListBox_SelectedIndexChanged); | ||||
// | // | ||||
// menuItem1 | |||||
// | |||||
this.menuItem1.Index = 2; | |||||
this.menuItem1.Text = "-"; | |||||
// | |||||
// ConfigForm | // ConfigForm | ||||
// | // | ||||
this.AcceptButton = this.OKButton; | this.AcceptButton = this.OKButton; | ||||
@@ -474,35 +354,19 @@ | |||||
private System.Windows.Forms.TextBox ServerPortTextBox; | private System.Windows.Forms.TextBox ServerPortTextBox; | ||||
private System.Windows.Forms.TextBox PasswordTextBox; | private System.Windows.Forms.TextBox PasswordTextBox; | ||||
private System.Windows.Forms.TextBox ProxyPortTextBox; | private System.Windows.Forms.TextBox ProxyPortTextBox; | ||||
private System.Windows.Forms.NotifyIcon notifyIcon1; | |||||
private System.Windows.Forms.Label label5; | private System.Windows.Forms.Label label5; | ||||
private System.Windows.Forms.ComboBox EncryptionSelect; | private System.Windows.Forms.ComboBox EncryptionSelect; | ||||
private System.Windows.Forms.Panel panel2; | private System.Windows.Forms.Panel panel2; | ||||
private System.Windows.Forms.Button OKButton; | private System.Windows.Forms.Button OKButton; | ||||
private System.Windows.Forms.Button MyCancelButton; | private System.Windows.Forms.Button MyCancelButton; | ||||
private System.Windows.Forms.Panel panel1; | private System.Windows.Forms.Panel panel1; | ||||
private System.Windows.Forms.ContextMenu contextMenu1; | |||||
private System.Windows.Forms.MenuItem enableItem; | |||||
private System.Windows.Forms.MenuItem aboutItem; | |||||
private System.Windows.Forms.MenuItem menuItem3; | |||||
private System.Windows.Forms.MenuItem quitItem; | |||||
private System.Windows.Forms.MenuItem ConfigItem; | |||||
private System.Windows.Forms.MenuItem editPACFileItem; | |||||
private System.Windows.Forms.Panel panel3; | private System.Windows.Forms.Panel panel3; | ||||
private System.Windows.Forms.Button DeleteButton; | private System.Windows.Forms.Button DeleteButton; | ||||
private System.Windows.Forms.Button AddButton; | private System.Windows.Forms.Button AddButton; | ||||
private System.Windows.Forms.GroupBox ServerGroupBox; | private System.Windows.Forms.GroupBox ServerGroupBox; | ||||
private System.Windows.Forms.ListBox ServersListBox; | private System.Windows.Forms.ListBox ServersListBox; | ||||
private System.Windows.Forms.MenuItem ServersItem; | |||||
private System.Windows.Forms.MenuItem SeperatorItem; | |||||
private System.Windows.Forms.MenuItem menuItem4; | |||||
private System.Windows.Forms.TextBox RemarksTextBox; | private System.Windows.Forms.TextBox RemarksTextBox; | ||||
private System.Windows.Forms.Label label6; | private System.Windows.Forms.Label label6; | ||||
private System.Windows.Forms.MenuItem QRCodeItem; | |||||
private System.Windows.Forms.MenuItem ShowLogItem; | |||||
private System.Windows.Forms.MenuItem ShareOverLANItem; | |||||
private System.Windows.Forms.MenuItem AutoStartupItem; | |||||
private System.Windows.Forms.MenuItem menuItem1; | |||||
} | } | ||||
} | } | ||||
@@ -25,79 +25,19 @@ namespace Shadowsocks.View | |||||
public ConfigForm(ShadowsocksController controller) | public ConfigForm(ShadowsocksController controller) | ||||
{ | { | ||||
InitializeComponent(); | InitializeComponent(); | ||||
LoadTrayIcon(); | |||||
notifyIcon1.ContextMenu = contextMenu1; | |||||
this.Icon = Icon.FromHandle(Resources.ssw128.GetHicon()); | |||||
this.controller = controller; | this.controller = controller; | ||||
controller.EnableStatusChanged += controller_EnableStatusChanged; | |||||
controller.ConfigChanged += controller_ConfigChanged; | controller.ConfigChanged += controller_ConfigChanged; | ||||
controller.PACFileReadyToOpen += controller_PACFileReadyToOpen; | |||||
controller.ShareOverLANStatusChanged += controller_ShareOverLANStatusChanged; | |||||
this.updateChecker = new UpdateChecker(); | |||||
updateChecker.NewVersionFound += updateChecker_NewVersionFound; | |||||
LoadCurrentConfiguration(); | LoadCurrentConfiguration(); | ||||
} | } | ||||
private void LoadTrayIcon() | |||||
{ | |||||
int dpi; | |||||
Graphics graphics = this.CreateGraphics(); | |||||
dpi = (int)graphics.DpiX; | |||||
graphics.Dispose(); | |||||
Bitmap icon = null; | |||||
if (dpi < 97) | |||||
{ | |||||
// dpi = 96; | |||||
icon = Resources.ss16; | |||||
} | |||||
else if (dpi < 121) | |||||
{ | |||||
// dpi = 120; | |||||
icon = Resources.ss20; | |||||
} | |||||
else | |||||
{ | |||||
icon = Resources.ss24; | |||||
} | |||||
notifyIcon1.Icon = Icon.FromHandle(icon.GetHicon()); | |||||
notifyIcon1.Visible = true; | |||||
this.Icon = Icon.FromHandle(Resources.ssw128.GetHicon()); | |||||
} | |||||
private void controller_ConfigChanged(object sender, EventArgs e) | private void controller_ConfigChanged(object sender, EventArgs e) | ||||
{ | { | ||||
LoadCurrentConfiguration(); | LoadCurrentConfiguration(); | ||||
} | } | ||||
private void controller_EnableStatusChanged(object sender, EventArgs e) | |||||
{ | |||||
enableItem.Checked = controller.GetConfiguration().enabled; | |||||
} | |||||
void controller_ShareOverLANStatusChanged(object sender, EventArgs e) | |||||
{ | |||||
ShareOverLANItem.Checked = controller.GetConfiguration().shareOverLan; | |||||
} | |||||
void controller_PACFileReadyToOpen(object sender, ShadowsocksController.PathEventArgs e) | |||||
{ | |||||
string argument = @"/select, " + e.Path; | |||||
System.Diagnostics.Process.Start("explorer.exe", argument); | |||||
} | |||||
void updateChecker_NewVersionFound(object sender, EventArgs e) | |||||
{ | |||||
notifyIcon1.BalloonTipTitle = "Shadowsocks " + updateChecker.LatestVersionNumber + " Update Found"; | |||||
notifyIcon1.BalloonTipText = "Click here to download"; | |||||
notifyIcon1.BalloonTipIcon = ToolTipIcon.Info; | |||||
notifyIcon1.BalloonTipClicked += notifyIcon1_BalloonTipClicked; | |||||
notifyIcon1.ShowBalloonTip(5000); | |||||
_isFirstRun = false; | |||||
} | |||||
void notifyIcon1_BalloonTipClicked(object sender, EventArgs e) | void notifyIcon1_BalloonTipClicked(object sender, EventArgs e) | ||||
{ | { | ||||
Process.Start(updateChecker.LatestVersionURL); | Process.Start(updateChecker.LatestVersionURL); | ||||
@@ -181,52 +121,11 @@ namespace Shadowsocks.View | |||||
_oldSelectedIndex = _modifiedConfiguration.index; | _oldSelectedIndex = _modifiedConfiguration.index; | ||||
ServersListBox.SelectedIndex = _modifiedConfiguration.index; | ServersListBox.SelectedIndex = _modifiedConfiguration.index; | ||||
LoadSelectedServer(); | LoadSelectedServer(); | ||||
UpdateServersMenu(); | |||||
enableItem.Checked = _modifiedConfiguration.enabled; | |||||
ShareOverLANItem.Checked = _modifiedConfiguration.shareOverLan; | |||||
AutoStartupItem.Checked = AutoStartup.Check(); | |||||
} | |||||
private void UpdateServersMenu() | |||||
{ | |||||
var items = ServersItem.MenuItems; | |||||
items.Clear(); | |||||
Configuration configuration = controller.GetConfiguration(); | |||||
for (int i = 0; i < configuration.configs.Count; i++) | |||||
{ | |||||
Server server = configuration.configs[i]; | |||||
MenuItem item = new MenuItem(string.IsNullOrEmpty(server.remarks) ? server.server + ":" + server.server_port : server.server + ":" + server.server_port + " (" + server.remarks + ")"); | |||||
item.Tag = i; | |||||
item.Click += AServerItem_Click; | |||||
items.Add(item); | |||||
} | |||||
items.Add(SeperatorItem); | |||||
items.Add(ConfigItem); | |||||
if (configuration.index >= 0 && configuration.index < configuration.configs.Count) | |||||
{ | |||||
items[configuration.index].Checked = true; | |||||
} | |||||
} | } | ||||
private void ConfigForm_Load(object sender, EventArgs e) | private void ConfigForm_Load(object sender, EventArgs e) | ||||
{ | { | ||||
if (!controller.GetConfiguration().isDefault) | |||||
{ | |||||
this.Opacity = 0; | |||||
BeginInvoke(new MethodInvoker(delegate | |||||
{ | |||||
this.Hide(); | |||||
})); | |||||
} | |||||
else | |||||
{ | |||||
_isFirstRun = true; | |||||
} | |||||
updateChecker.CheckUpdate(); | |||||
} | } | ||||
private void ServersListBox_SelectedIndexChanged(object sender, EventArgs e) | private void ServersListBox_SelectedIndexChanged(object sender, EventArgs e) | ||||
@@ -277,28 +176,6 @@ namespace Shadowsocks.View | |||||
LoadSelectedServer(); | LoadSelectedServer(); | ||||
} | } | ||||
private void Config_Click(object sender, EventArgs e) | |||||
{ | |||||
ShowWindow(); | |||||
} | |||||
private void Quit_Click(object sender, EventArgs e) | |||||
{ | |||||
this.Close(); | |||||
} | |||||
private void ShowFirstTimeBalloon() | |||||
{ | |||||
if (_isFirstRun) | |||||
{ | |||||
notifyIcon1.BalloonTipTitle = "Shadowsocks is here"; | |||||
notifyIcon1.BalloonTipText = "You can turn on/off Shadowsocks in the context menu"; | |||||
notifyIcon1.BalloonTipIcon = ToolTipIcon.Info; | |||||
notifyIcon1.ShowBalloonTip(0); | |||||
_isFirstRun = false; | |||||
} | |||||
} | |||||
private void OKButton_Click(object sender, EventArgs e) | private void OKButton_Click(object sender, EventArgs e) | ||||
{ | { | ||||
if (!SaveOldSelectedServer()) | if (!SaveOldSelectedServer()) | ||||
@@ -312,60 +189,11 @@ namespace Shadowsocks.View | |||||
} | } | ||||
controller.SaveServers(_modifiedConfiguration.configs); | controller.SaveServers(_modifiedConfiguration.configs); | ||||
this.Hide(); | this.Hide(); | ||||
ShowFirstTimeBalloon(); | |||||
} | } | ||||
private void CancelButton_Click(object sender, EventArgs e) | private void CancelButton_Click(object sender, EventArgs e) | ||||
{ | { | ||||
this.Hide(); | |||||
LoadCurrentConfiguration(); | |||||
ShowFirstTimeBalloon(); | |||||
} | |||||
private void ConfigForm_FormClosed(object sender, FormClosedEventArgs e) | |||||
{ | |||||
controller.Stop(); | |||||
} | |||||
private void AboutItem_Click(object sender, EventArgs e) | |||||
{ | |||||
Process.Start("https://github.com/clowwindy/shadowsocks-csharp"); | |||||
} | |||||
private void notifyIcon1_DoubleClick(object sender, EventArgs e) | |||||
{ | |||||
ShowWindow(); | |||||
} | |||||
private void EnableItem_Click(object sender, EventArgs e) | |||||
{ | |||||
enableItem.Checked = !enableItem.Checked; | |||||
controller.ToggleEnable(enableItem.Checked); | |||||
} | |||||
private void ShareOverLANItem_Click(object sender, EventArgs e) | |||||
{ | |||||
ShareOverLANItem.Checked = !ShareOverLANItem.Checked; | |||||
controller.ToggleShareOverLAN(ShareOverLANItem.Checked); | |||||
} | |||||
private void EditPACFileItem_Click(object sender, EventArgs e) | |||||
{ | |||||
controller.TouchPACFile(); | |||||
} | |||||
private void AServerItem_Click(object sender, EventArgs e) | |||||
{ | |||||
MenuItem item = (MenuItem)sender; | |||||
controller.SelectServerIndex((int)item.Tag); | |||||
} | |||||
private void ShowLogItem_Click(object sender, EventArgs e) | |||||
{ | |||||
string argument = Logging.LogFile; | |||||
System.Diagnostics.Process.Start("notepad.exe", argument); | |||||
this.Close(); | |||||
} | } | ||||
private void ConfigForm_Shown(object sender, EventArgs e) | private void ConfigForm_Shown(object sender, EventArgs e) | ||||
@@ -373,18 +201,10 @@ namespace Shadowsocks.View | |||||
IPTextBox.Focus(); | IPTextBox.Focus(); | ||||
} | } | ||||
private void QRCodeItem_Click(object sender, EventArgs e) | |||||
private void ConfigForm_FormClosed(object sender, FormClosedEventArgs e) | |||||
{ | { | ||||
QRCodeForm qrCodeForm = new QRCodeForm(controller.GetQRCodeForCurrentServer()); | |||||
qrCodeForm.Icon = this.Icon; | |||||
qrCodeForm.Show(); | |||||
controller.ConfigChanged -= controller_ConfigChanged; | |||||
} | } | ||||
private void AutoStartupItem_Click(object sender, EventArgs e) { | |||||
AutoStartupItem.Checked = !AutoStartupItem.Checked; | |||||
if (!AutoStartup.Set(AutoStartupItem.Checked)) { | |||||
MessageBox.Show("Failed to edit registry"); | |||||
} | |||||
} | |||||
} | } | ||||
} | } |
@@ -112,15 +112,9 @@ | |||||
<value>2.0</value> | <value>2.0</value> | ||||
</resheader> | </resheader> | ||||
<resheader name="reader"> | <resheader name="reader"> | ||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||||
</resheader> | </resheader> | ||||
<resheader name="writer"> | <resheader name="writer"> | ||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||||
</resheader> | </resheader> | ||||
<metadata name="notifyIcon1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> | |||||
<value>17, 17</value> | |||||
</metadata> | |||||
<metadata name="contextMenu1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> | |||||
<value>146, 19</value> | |||||
</metadata> | |||||
</root> | </root> |
@@ -0,0 +1,388 @@ | |||||
using Shadowsocks.Controller; | |||||
using Shadowsocks.Model; | |||||
using Shadowsocks.Properties; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Diagnostics; | |||||
using System.Drawing; | |||||
using System.Text; | |||||
using System.Windows.Forms; | |||||
namespace Shadowsocks.View | |||||
{ | |||||
public class MenuViewController | |||||
{ | |||||
// yes this is just a menu view controller | |||||
// when config form is closed, it moves away from RAM | |||||
// and it should just does anything related to the config form | |||||
private ShadowsocksController controller; | |||||
private UpdateChecker updateChecker; | |||||
private NotifyIcon notifyIcon1; | |||||
private ContextMenu contextMenu1; | |||||
// this is a copy of configuration that we are working on | |||||
private bool _isFirstRun; | |||||
private MenuItem enableItem; | |||||
private MenuItem AutoStartupItem; | |||||
private MenuItem ShareOverLANItem; | |||||
private MenuItem SeperatorItem; | |||||
private MenuItem ConfigItem; | |||||
private MenuItem menuItem4; | |||||
private MenuItem editPACFileItem; | |||||
private MenuItem QRCodeItem; | |||||
private MenuItem ShowLogItem; | |||||
private MenuItem aboutItem; | |||||
private MenuItem ServersItem; | |||||
private MenuItem menuItem3; | |||||
private MenuItem quitItem; | |||||
private MenuItem menuItem1; | |||||
private ConfigForm configForm; | |||||
public MenuViewController(ShadowsocksController controller) | |||||
{ | |||||
LoadMenu(); | |||||
LoadTrayIcon(); | |||||
this.controller = controller; | |||||
controller.EnableStatusChanged += controller_EnableStatusChanged; | |||||
controller.ConfigChanged += controller_ConfigChanged; | |||||
controller.PACFileReadyToOpen += controller_PACFileReadyToOpen; | |||||
controller.ShareOverLANStatusChanged += controller_ShareOverLANStatusChanged; | |||||
this.updateChecker = new UpdateChecker(); | |||||
updateChecker.NewVersionFound += updateChecker_NewVersionFound; | |||||
LoadCurrentConfiguration(); | |||||
updateChecker.CheckUpdate(); | |||||
if (controller.GetConfiguration().isDefault) | |||||
{ | |||||
_isFirstRun = true; | |||||
ShowConfigForm(); | |||||
} | |||||
} | |||||
private void LoadTrayIcon() | |||||
{ | |||||
int dpi; | |||||
Graphics graphics = Graphics.FromHwnd(IntPtr.Zero); | |||||
dpi = (int)graphics.DpiX; | |||||
graphics.Dispose(); | |||||
Bitmap icon = null; | |||||
if (dpi < 97) | |||||
{ | |||||
// dpi = 96; | |||||
icon = Resources.ss16; | |||||
} | |||||
else if (dpi < 121) | |||||
{ | |||||
// dpi = 120; | |||||
icon = Resources.ss20; | |||||
} | |||||
else | |||||
{ | |||||
icon = Resources.ss24; | |||||
} | |||||
notifyIcon1 = new NotifyIcon(); | |||||
notifyIcon1.Icon = Icon.FromHandle(icon.GetHicon()); | |||||
notifyIcon1.Visible = true; | |||||
notifyIcon1.ContextMenu = contextMenu1; | |||||
notifyIcon1.DoubleClick +=notifyIcon1_DoubleClick; | |||||
} | |||||
private void LoadMenu() | |||||
{ | |||||
this.contextMenu1 = new System.Windows.Forms.ContextMenu(); | |||||
this.enableItem = new System.Windows.Forms.MenuItem(); | |||||
this.AutoStartupItem = new System.Windows.Forms.MenuItem(); | |||||
this.ShareOverLANItem = new System.Windows.Forms.MenuItem(); | |||||
this.ServersItem = new System.Windows.Forms.MenuItem(); | |||||
this.SeperatorItem = new System.Windows.Forms.MenuItem(); | |||||
this.ConfigItem = new System.Windows.Forms.MenuItem(); | |||||
this.menuItem4 = new System.Windows.Forms.MenuItem(); | |||||
this.editPACFileItem = new System.Windows.Forms.MenuItem(); | |||||
this.QRCodeItem = new System.Windows.Forms.MenuItem(); | |||||
this.ShowLogItem = new System.Windows.Forms.MenuItem(); | |||||
this.aboutItem = new System.Windows.Forms.MenuItem(); | |||||
this.menuItem3 = new System.Windows.Forms.MenuItem(); | |||||
this.quitItem = new System.Windows.Forms.MenuItem(); | |||||
this.menuItem1 = new System.Windows.Forms.MenuItem(); | |||||
// | |||||
// contextMenu1 | |||||
// | |||||
this.contextMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { | |||||
this.enableItem, | |||||
this.ServersItem, | |||||
this.menuItem1, | |||||
this.AutoStartupItem, | |||||
this.ShareOverLANItem, | |||||
this.editPACFileItem, | |||||
this.menuItem4, | |||||
this.QRCodeItem, | |||||
this.ShowLogItem, | |||||
this.aboutItem, | |||||
this.menuItem3, | |||||
this.quitItem}); | |||||
// | |||||
// enableItem | |||||
// | |||||
this.enableItem.Index = 0; | |||||
this.enableItem.Text = "&Enable"; | |||||
this.enableItem.Click += new System.EventHandler(this.EnableItem_Click); | |||||
// | |||||
// AutoStartupItem | |||||
// | |||||
this.AutoStartupItem.Index = 3; | |||||
this.AutoStartupItem.Text = "Start on Boot"; | |||||
this.AutoStartupItem.Click += new System.EventHandler(this.AutoStartupItem_Click); | |||||
// | |||||
// ShareOverLANItem | |||||
// | |||||
this.ShareOverLANItem.Index = 4; | |||||
this.ShareOverLANItem.Text = "Share over LAN"; | |||||
this.ShareOverLANItem.Click += new System.EventHandler(this.ShareOverLANItem_Click); | |||||
// | |||||
// ServersItem | |||||
// | |||||
this.ServersItem.Index = 1; | |||||
this.ServersItem.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { | |||||
this.SeperatorItem, | |||||
this.ConfigItem}); | |||||
this.ServersItem.Text = "&Servers"; | |||||
// | |||||
// SeperatorItem | |||||
// | |||||
this.SeperatorItem.Index = 0; | |||||
this.SeperatorItem.Text = "-"; | |||||
// | |||||
// ConfigItem | |||||
// | |||||
this.ConfigItem.Index = 1; | |||||
this.ConfigItem.Text = "Edit Servers..."; | |||||
this.ConfigItem.Click += new System.EventHandler(this.Config_Click); | |||||
// | |||||
// menuItem4 | |||||
// | |||||
this.menuItem4.Index = 6; | |||||
this.menuItem4.Text = "-"; | |||||
// | |||||
// editPACFileItem | |||||
// | |||||
this.editPACFileItem.Index = 5; | |||||
this.editPACFileItem.Text = "Edit &PAC File..."; | |||||
this.editPACFileItem.Click += new System.EventHandler(this.EditPACFileItem_Click); | |||||
// | |||||
// QRCodeItem | |||||
// | |||||
this.QRCodeItem.Index = 7; | |||||
this.QRCodeItem.Text = "Show &QRCode..."; | |||||
this.QRCodeItem.Click += new System.EventHandler(this.QRCodeItem_Click); | |||||
// | |||||
// ShowLogItem | |||||
// | |||||
this.ShowLogItem.Index = 8; | |||||
this.ShowLogItem.Text = "Show Logs..."; | |||||
this.ShowLogItem.Click += new System.EventHandler(this.ShowLogItem_Click); | |||||
// | |||||
// aboutItem | |||||
// | |||||
this.aboutItem.Index = 9; | |||||
this.aboutItem.Text = "About..."; | |||||
this.aboutItem.Click += new System.EventHandler(this.AboutItem_Click); | |||||
// | |||||
// menuItem3 | |||||
// | |||||
this.menuItem3.Index = 10; | |||||
this.menuItem3.Text = "-"; | |||||
// | |||||
// quitItem | |||||
// | |||||
this.quitItem.Index = 11; | |||||
this.quitItem.Text = "&Quit"; | |||||
this.quitItem.Click += new System.EventHandler(this.Quit_Click); | |||||
// | |||||
// menuItem1 | |||||
// | |||||
this.menuItem1.Index = 2; | |||||
this.menuItem1.Text = "-"; | |||||
} | |||||
private void controller_ConfigChanged(object sender, EventArgs e) | |||||
{ | |||||
LoadCurrentConfiguration(); | |||||
} | |||||
private void controller_EnableStatusChanged(object sender, EventArgs e) | |||||
{ | |||||
enableItem.Checked = controller.GetConfiguration().enabled; | |||||
} | |||||
void controller_ShareOverLANStatusChanged(object sender, EventArgs e) | |||||
{ | |||||
ShareOverLANItem.Checked = controller.GetConfiguration().shareOverLan; | |||||
} | |||||
void controller_PACFileReadyToOpen(object sender, ShadowsocksController.PathEventArgs e) | |||||
{ | |||||
string argument = @"/select, " + e.Path; | |||||
System.Diagnostics.Process.Start("explorer.exe", argument); | |||||
} | |||||
void updateChecker_NewVersionFound(object sender, EventArgs e) | |||||
{ | |||||
notifyIcon1.BalloonTipTitle = "Shadowsocks " + updateChecker.LatestVersionNumber + " Update Found"; | |||||
notifyIcon1.BalloonTipText = "Click here to download"; | |||||
notifyIcon1.BalloonTipIcon = ToolTipIcon.Info; | |||||
notifyIcon1.BalloonTipClicked += notifyIcon1_BalloonTipClicked; | |||||
notifyIcon1.ShowBalloonTip(5000); | |||||
_isFirstRun = false; | |||||
} | |||||
void notifyIcon1_BalloonTipClicked(object sender, EventArgs e) | |||||
{ | |||||
System.Diagnostics.Process.Start(updateChecker.LatestVersionURL); | |||||
} | |||||
private void LoadCurrentConfiguration() | |||||
{ | |||||
Configuration config = controller.GetConfiguration(); | |||||
UpdateServersMenu(); | |||||
enableItem.Checked = config.enabled; | |||||
ShareOverLANItem.Checked = config.shareOverLan; | |||||
AutoStartupItem.Checked = AutoStartup.Check(); | |||||
} | |||||
private void UpdateServersMenu() | |||||
{ | |||||
var items = ServersItem.MenuItems; | |||||
items.Clear(); | |||||
Configuration configuration = controller.GetConfiguration(); | |||||
for (int i = 0; i < configuration.configs.Count; i++) | |||||
{ | |||||
Server server = configuration.configs[i]; | |||||
MenuItem item = new MenuItem(string.IsNullOrEmpty(server.remarks) ? server.server + ":" + server.server_port : server.server + ":" + server.server_port + " (" + server.remarks + ")"); | |||||
item.Tag = i; | |||||
item.Click += AServerItem_Click; | |||||
items.Add(item); | |||||
} | |||||
items.Add(SeperatorItem); | |||||
items.Add(ConfigItem); | |||||
if (configuration.index >= 0 && configuration.index < configuration.configs.Count) | |||||
{ | |||||
items[configuration.index].Checked = true; | |||||
} | |||||
} | |||||
private void ShowConfigForm() | |||||
{ | |||||
if (configForm != null) | |||||
{ | |||||
configForm.Focus(); | |||||
} | |||||
else | |||||
{ | |||||
configForm = new ConfigForm(controller); | |||||
configForm.Show(); | |||||
configForm.FormClosed += configForm_FormClosed; | |||||
} | |||||
} | |||||
void configForm_FormClosed(object sender, FormClosedEventArgs e) | |||||
{ | |||||
configForm = null; | |||||
GC.Collect(); | |||||
GC.WaitForPendingFinalizers(); | |||||
ShowFirstTimeBalloon(); | |||||
} | |||||
private void Config_Click(object sender, EventArgs e) | |||||
{ | |||||
ShowConfigForm(); | |||||
} | |||||
private void Quit_Click(object sender, EventArgs e) | |||||
{ | |||||
controller.Stop(); | |||||
notifyIcon1.Visible = false; | |||||
Application.Exit(); | |||||
} | |||||
private void ShowFirstTimeBalloon() | |||||
{ | |||||
if (_isFirstRun) | |||||
{ | |||||
notifyIcon1.BalloonTipTitle = "Shadowsocks is here"; | |||||
notifyIcon1.BalloonTipText = "You can turn on/off Shadowsocks in the context menu"; | |||||
notifyIcon1.BalloonTipIcon = ToolTipIcon.Info; | |||||
notifyIcon1.ShowBalloonTip(0); | |||||
_isFirstRun = false; | |||||
} | |||||
} | |||||
private void AboutItem_Click(object sender, EventArgs e) | |||||
{ | |||||
Process.Start("https://github.com/clowwindy/shadowsocks-csharp"); | |||||
} | |||||
private void notifyIcon1_DoubleClick(object sender, EventArgs e) | |||||
{ | |||||
ShowConfigForm(); | |||||
} | |||||
private void EnableItem_Click(object sender, EventArgs e) | |||||
{ | |||||
enableItem.Checked = !enableItem.Checked; | |||||
controller.ToggleEnable(enableItem.Checked); | |||||
} | |||||
private void ShareOverLANItem_Click(object sender, EventArgs e) | |||||
{ | |||||
ShareOverLANItem.Checked = !ShareOverLANItem.Checked; | |||||
controller.ToggleShareOverLAN(ShareOverLANItem.Checked); | |||||
} | |||||
private void EditPACFileItem_Click(object sender, EventArgs e) | |||||
{ | |||||
controller.TouchPACFile(); | |||||
} | |||||
private void AServerItem_Click(object sender, EventArgs e) | |||||
{ | |||||
MenuItem item = (MenuItem)sender; | |||||
controller.SelectServerIndex((int)item.Tag); | |||||
} | |||||
private void ShowLogItem_Click(object sender, EventArgs e) | |||||
{ | |||||
string argument = Logging.LogFile; | |||||
System.Diagnostics.Process.Start("notepad.exe", argument); | |||||
} | |||||
private void QRCodeItem_Click(object sender, EventArgs e) | |||||
{ | |||||
QRCodeForm qrCodeForm = new QRCodeForm(controller.GetQRCodeForCurrentServer()); | |||||
//qrCodeForm.Icon = this.Icon; | |||||
// TODO | |||||
qrCodeForm.Show(); | |||||
} | |||||
private void AutoStartupItem_Click(object sender, EventArgs e) { | |||||
AutoStartupItem.Checked = !AutoStartupItem.Checked; | |||||
if (!AutoStartup.Set(AutoStartupItem.Checked)) { | |||||
MessageBox.Show("Failed to edit registry"); | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -20,6 +20,7 @@ namespace Shadowsocks.View | |||||
{ | { | ||||
this.code = code; | this.code = code; | ||||
InitializeComponent(); | InitializeComponent(); | ||||
this.Icon = Icon.FromHandle(Resources.ssw128.GetHicon()); | |||||
} | } | ||||
private void GenQR(string ssconfig) | private void GenQR(string ssconfig) | ||||
@@ -96,6 +96,7 @@ | |||||
<Compile Include="Properties\AssemblyInfo.cs" /> | <Compile Include="Properties\AssemblyInfo.cs" /> | ||||
<Compile Include="Controller\ShadowsocksController.cs" /> | <Compile Include="Controller\ShadowsocksController.cs" /> | ||||
<Compile Include="Controller\SystemProxy.cs" /> | <Compile Include="Controller\SystemProxy.cs" /> | ||||
<Compile Include="View\MenuViewController.cs" /> | |||||
<Compile Include="View\QRCodeForm.cs"> | <Compile Include="View\QRCodeForm.cs"> | ||||
<SubType>Form</SubType> | <SubType>Form</SubType> | ||||
</Compile> | </Compile> | ||||