Browse Source

👁 ServerSharingView & ServerSharingViewModel

- Use ElementHost in QRCodeForm
- Cleanup: Server.Equals
tags/4.2.1.0
database64128 4 years ago
parent
commit
3aaff9cc7e
7 changed files with 196 additions and 110 deletions
  1. +1
    -5
      shadowsocks-csharp/Model/Server.cs
  2. +16
    -50
      shadowsocks-csharp/View/QRCodeForm.Designer.cs
  3. +0
    -55
      shadowsocks-csharp/View/QRCodeForm.cs
  4. +109
    -0
      shadowsocks-csharp/ViewModels/ServerSharingViewModel.cs
  5. +36
    -0
      shadowsocks-csharp/Views/ServerSharingView.xaml
  6. +24
    -0
      shadowsocks-csharp/Views/ServerSharingView.xaml.cs
  7. +10
    -0
      shadowsocks-csharp/shadowsocks-csharp.csproj

+ 1
- 5
shadowsocks-csharp/Model/Server.cs View File

@@ -58,11 +58,7 @@ namespace Shadowsocks.Model
return server.GetHashCode() ^ server_port; return server.GetHashCode() ^ server_port;
} }
public override bool Equals(object obj)
{
Server o2 = (Server)obj;
return server == o2.server && server_port == o2.server_port;
}
public override bool Equals(object obj) => obj is Server o2 && server == o2.server && server_port == o2.server_port;
public override string ToString() public override string ToString()
{ {


+ 16
- 50
shadowsocks-csharp/View/QRCodeForm.Designer.cs View File

@@ -28,73 +28,39 @@
/// </summary> /// </summary>
private void InitializeComponent() private void InitializeComponent()
{ {
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.listBox1 = new System.Windows.Forms.ListBox();
this.textBoxURL = new System.Windows.Forms.TextBox();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.elementHost1 = new System.Windows.Forms.Integration.ElementHost();
this.serverSharingView1 = new Shadowsocks.Views.ServerSharingView();
this.SuspendLayout(); this.SuspendLayout();
// //
// pictureBox1
// elementHost1
// //
this.pictureBox1.Location = new System.Drawing.Point(10, 10);
this.pictureBox1.Margin = new System.Windows.Forms.Padding(0);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(210, 210);
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage;
this.pictureBox1.TabIndex = 1;
this.pictureBox1.TabStop = false;
//
// listBox1
//
this.listBox1.DisplayMember = "Value";
this.listBox1.FormattingEnabled = true;
this.listBox1.ItemHeight = 12;
this.listBox1.Location = new System.Drawing.Point(224, 10);
this.listBox1.Name = "listBox1";
this.listBox1.ScrollAlwaysVisible = true;
this.listBox1.Size = new System.Drawing.Size(227, 208);
this.listBox1.TabIndex = 2;
this.listBox1.ValueMember = "Key";
this.listBox1.SelectedIndexChanged += new System.EventHandler(this.listBox1_SelectedIndexChanged);
//
// textBoxURL
//
this.textBoxURL.Location = new System.Drawing.Point(10, 227);
this.textBoxURL.Name = "textBoxURL";
this.textBoxURL.ReadOnly = true;
this.textBoxURL.Size = new System.Drawing.Size(441, 21);
this.textBoxURL.TabIndex = 3;
this.textBoxURL.Click += new System.EventHandler(this.textBoxURL_Click);
this.elementHost1.Dock = System.Windows.Forms.DockStyle.Fill;
this.elementHost1.Location = new System.Drawing.Point(0, 0);
this.elementHost1.Margin = new System.Windows.Forms.Padding(0);
this.elementHost1.Name = "elementHost1";
this.elementHost1.Size = new System.Drawing.Size(600, 340);
this.elementHost1.TabIndex = 0;
this.elementHost1.Text = "elementHost1";
this.elementHost1.Child = this.serverSharingView1;
// //
// QRCodeForm // QRCodeForm
// //
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
this.AutoSize = true;
this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.BackColor = System.Drawing.Color.White; this.BackColor = System.Drawing.Color.White;
this.ClientSize = new System.Drawing.Size(457, 257);
this.Controls.Add(this.textBoxURL);
this.Controls.Add(this.listBox1);
this.Controls.Add(this.pictureBox1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.ClientSize = new System.Drawing.Size(600, 340);
this.Controls.Add(this.elementHost1);
this.Margin = new System.Windows.Forms.Padding(8);
this.Name = "QRCodeForm"; this.Name = "QRCodeForm";
this.Padding = new System.Windows.Forms.Padding(10);
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "QRCode and URL"; this.Text = "QRCode and URL";
this.Load += new System.EventHandler(this.QRCodeForm_Load); this.Load += new System.EventHandler(this.QRCodeForm_Load);
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.ResumeLayout(false); this.ResumeLayout(false);
this.PerformLayout();
} }
#endregion #endregion
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.ListBox listBox1;
private System.Windows.Forms.TextBox textBoxURL;
private System.Windows.Forms.Integration.ElementHost elementHost1;
private Views.ServerSharingView serverSharingView1;
} }
} }

+ 0
- 55
shadowsocks-csharp/View/QRCodeForm.cs View File

@@ -27,64 +27,9 @@ namespace Shadowsocks.View
this.Text = I18N.GetString("QRCode and URL"); this.Text = I18N.GetString("QRCode and URL");
} }
private void GenQR(string ssconfig)
{
string qrText = ssconfig;
QRCode code = ZXing.QrCode.Internal.Encoder.encode(qrText, ErrorCorrectionLevel.M);
ByteMatrix m = code.Matrix;
int blockSize = Math.Max(pictureBox1.Height/m.Height, 1);
var qrWidth = m.Width*blockSize;
var qrHeight = m.Height*blockSize;
var dWidth = pictureBox1.Width - qrWidth;
var dHeight = pictureBox1.Height - qrHeight;
var maxD = Math.Max(dWidth, dHeight);
pictureBox1.SizeMode = maxD >= 7*blockSize ? PictureBoxSizeMode.Zoom : PictureBoxSizeMode.CenterImage;
Bitmap drawArea = new Bitmap((m.Width*blockSize), (m.Height*blockSize));
using (Graphics g = Graphics.FromImage(drawArea))
{
g.Clear(Color.White);
using (Brush b = new SolidBrush(Color.Black))
{
for (int row = 0; row < m.Width; row++)
{
for (int col = 0; col < m.Height; col++)
{
if (m[row, col] != 0)
{
g.FillRectangle(b, blockSize*row, blockSize*col, blockSize, blockSize);
}
}
}
}
}
pictureBox1.Image = drawArea;
}
private void QRCodeForm_Load(object sender, EventArgs e) private void QRCodeForm_Load(object sender, EventArgs e)
{ {
Configuration config = Configuration.Load();
List<KeyValuePair<string, string>> serverDatas = config.configs.Select(
server =>
new KeyValuePair<string, string>(server.GetURL(config.generateLegacyUrl), server.ToString())
).ToList();
listBox1.DataSource = serverDatas;
int selectIndex = serverDatas.FindIndex(serverData => serverData.Key.StartsWith(code));
if (selectIndex >= 0) listBox1.SetSelected(selectIndex, true);
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
var url = (sender as ListBox)?.SelectedValue.ToString();
GenQR(url);
textBoxURL.Text = url;
}
private void textBoxURL_Click(object sender, EventArgs e)
{
textBoxURL.SelectAll();
} }
} }
} }

+ 109
- 0
shadowsocks-csharp/ViewModels/ServerSharingViewModel.cs View File

@@ -0,0 +1,109 @@
using ReactiveUI;
using Shadowsocks.Model;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Windows.Media.Imaging;

namespace Shadowsocks.ViewModels
{
public class ServerSharingViewModel : ReactiveObject
{
/// <summary>
/// The view model class for the server sharing user control.
/// </summary>
public ServerSharingViewModel()
{
_config = Configuration.Load();
_servers = _config.configs;
_selectedServer = _servers.First();
//_selectedServerUrlImage = new BitmapImage();
UpdateUrlAndImage();
}

private readonly Configuration _config;

private List<Server> _servers;
private Server _selectedServer;
private string _selectedServerUrl;
private BitmapImage _selectedServerUrlImage;

/// <summary>
/// Called when SelectedServer changed
/// to update SelectedServerUrl and SelectedServerUrlImage
/// </summary>
private void UpdateUrlAndImage()
{
// update SelectedServerUrl
SelectedServerUrl = _selectedServer.GetURL(_config.generateLegacyUrl);

// generate QR code
var qrCode = ZXing.QrCode.Internal.Encoder.encode(_selectedServerUrl, ZXing.QrCode.Internal.ErrorCorrectionLevel.L);
var byteMatrix = qrCode.Matrix;

// paint bitmap
int blockSize = Math.Max(1024 / byteMatrix.Height, 1);
Bitmap drawArea = new Bitmap((byteMatrix.Width * blockSize), (byteMatrix.Height * blockSize));
using (var graphics = Graphics.FromImage(drawArea))
{
graphics.Clear(Color.White);
using (var solidBrush = new SolidBrush(Color.Black))
{
for (int row = 0; row < byteMatrix.Width; row++)
{
for (int column = 0; column < byteMatrix.Height; column++)
{
if (byteMatrix[row, column] != 0)
{
graphics.FillRectangle(solidBrush, blockSize * row, blockSize * column, blockSize, blockSize);
}
}
}
}
}

// transform to BitmapImage for binding
BitmapImage bitmapImage = new BitmapImage();
using (MemoryStream memoryStream = new MemoryStream())
{
drawArea.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Bmp);
memoryStream.Position = 0;
bitmapImage.BeginInit();
bitmapImage.StreamSource = memoryStream;
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
}
SelectedServerUrlImage = bitmapImage;
}

public List<Server> Servers
{
get => _servers;
set => this.RaiseAndSetIfChanged(ref _servers, value);
}

public Server SelectedServer
{
get => _selectedServer;
set
{
this.RaiseAndSetIfChanged(ref _selectedServer, value);
UpdateUrlAndImage();
}
}

public string SelectedServerUrl
{
get => _selectedServerUrl;
set => this.RaiseAndSetIfChanged(ref _selectedServerUrl, value);
}

public BitmapImage SelectedServerUrlImage
{
get => _selectedServerUrlImage;
set => this.RaiseAndSetIfChanged(ref _selectedServerUrlImage, value);
}
}
}

+ 36
- 0
shadowsocks-csharp/Views/ServerSharingView.xaml View File

@@ -0,0 +1,36 @@
<UserControl x:Class="Shadowsocks.Views.ServerSharingView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Shadowsocks.Views"
mc:Ignorable="d"
d:DesignHeight="320" d:DesignWidth="600">
<Grid Margin="8">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Grid.Row="0"
Grid.Column="0"
Margin="8"
Source="{Binding SelectedServerUrlImage}"/>
<ListBox Grid.Row="0"
Grid.Column="1"
Margin="8"
ItemsSource="{Binding Servers}"
SelectedItem="{Binding SelectedServer}"/>
<TextBox x:Name="urlTextBox"
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
Margin="8"
IsReadOnly="True"
Text="{Binding SelectedServerUrl}"
PreviewMouseDoubleClick="urlTextBox_PreviewMouseDoubleClick"/>
</Grid>
</UserControl>

+ 24
- 0
shadowsocks-csharp/Views/ServerSharingView.xaml.cs View File

@@ -0,0 +1,24 @@
using Shadowsocks.ViewModels;
using System.Windows.Controls;
using System.Windows.Input;

namespace Shadowsocks.Views
{
/// <summary>
/// Interaction logic for ServerSharingView.xaml
/// </summary>
public partial class ServerSharingView : UserControl
{
public ServerSharingView()
{
InitializeComponent();

DataContext = new ServerSharingViewModel();
}

private void urlTextBox_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
urlTextBox.SelectAll();
}
}
}

+ 10
- 0
shadowsocks-csharp/shadowsocks-csharp.csproj View File

@@ -268,6 +268,7 @@
<Compile Include="Util\SystemProxy\Sysproxy.cs" /> <Compile Include="Util\SystemProxy\Sysproxy.cs" />
<Compile Include="Util\Util.cs" /> <Compile Include="Util\Util.cs" />
<Compile Include="Util\ViewUtils.cs" /> <Compile Include="Util\ViewUtils.cs" />
<Compile Include="ViewModels\ServerSharingViewModel.cs" />
<Compile Include="View\ConfigForm.cs"> <Compile Include="View\ConfigForm.cs">
<SubType>Form</SubType> <SubType>Form</SubType>
</Compile> </Compile>
@@ -320,6 +321,9 @@
<Compile Include="View\QRCodeSplashForm.cs"> <Compile Include="View\QRCodeSplashForm.cs">
<SubType>Form</SubType> <SubType>Form</SubType>
</Compile> </Compile>
<Compile Include="Views\ServerSharingView.xaml.cs">
<DependentUpon>ServerSharingView.xaml</DependentUpon>
</Compile>
<Compile Include="View\StatisticsStrategyConfigurationForm.cs"> <Compile Include="View\StatisticsStrategyConfigurationForm.cs">
<SubType>Form</SubType> <SubType>Form</SubType>
</Compile> </Compile>
@@ -416,6 +420,12 @@
<Install>true</Install> <Install>true</Install>
</BootstrapperPackage> </BootstrapperPackage>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Page Include="Views\ServerSharingView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup /> <ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Fody.4.2.1\build\Fody.targets" Condition="Exists('..\packages\Fody.4.2.1\build\Fody.targets')" /> <Import Project="..\packages\Fody.4.2.1\build\Fody.targets" Condition="Exists('..\packages\Fody.4.2.1\build\Fody.targets')" />


Loading…
Cancel
Save