This commit is contained in:
Wiesław Šoltés 2015-08-04 19:44:25 +02:00
Родитель ddcb10c4da
Коммит 8cac594725
5 изменённых файлов: 236 добавлений и 31 удалений

Просмотреть файл

@ -40,6 +40,8 @@ namespace SpiroNet.Wpf
private int _hitShapePointIndex = -1;
private double _width = 600;
private double _height = 600;
private bool _isStroked = true;
private bool _isFilled = false;
private bool _isClosed = false;
private bool _isTagged = false;
private SpiroPointType _pointType = SpiroPointType.G4;
@ -88,6 +90,18 @@ namespace SpiroNet.Wpf
set { Update(ref _height, value); }
}
public bool IsStroked
{
get { return _isStroked; }
set { Update(ref _isStroked, value); }
}
public bool IsFilled
{
get { return _isFilled; }
set { Update(ref _isFilled, value); }
}
public bool IsClosed
{
get { return _isClosed; }
@ -128,6 +142,10 @@ namespace SpiroNet.Wpf
public ICommand ExitCommand { get; set; }
public ICommand IsStrokedCommand { get; set; }
public ICommand IsFilledCommand { get; set; }
public ICommand IsClosedCommand { get; set; }
public ICommand IsTaggedCommand { get; set; }
@ -138,6 +156,26 @@ namespace SpiroNet.Wpf
public Action Invalidate { get; set; }
public void ToggleIsStroked()
{
IsStroked = !IsStroked;
if (_shape != null)
{
_shape.IsStroked = IsStroked;
Invalidate();
}
}
public void ToggleIsFilled()
{
IsFilled = !IsFilled;
if (_shape != null)
{
_shape.IsFilled = IsFilled;
Invalidate();
}
}
public void ToggleIsClosed()
{
IsClosed = !IsClosed;
@ -172,6 +210,8 @@ namespace SpiroNet.Wpf
private void NewShape()
{
_shape = new PathShape();
_shape.IsStroked = IsStroked;
_shape.IsFilled = IsFilled;
_shape.IsClosed = IsClosed;
_shape.IsTagged = IsTagged;
_shape.Points = new ObservableCollection<SpiroControlPoint>();
@ -396,17 +436,17 @@ namespace SpiroNet.Wpf
Invalidate();
}
public void Open(string path)
public void OpenDrawing(string path)
{
using (var f = System.IO.File.OpenText(path))
{
var json = f.ReadToEnd();
var drawing = JsonSerializer.Deserialize<PathDrawing>(json);
Open(drawing);
OpenDrawing(drawing);
}
}
public void Open(PathDrawing drawing)
public void OpenDrawing(PathDrawing drawing)
{
Width = drawing.Width;
Height = drawing.Height;
@ -421,7 +461,7 @@ namespace SpiroNet.Wpf
Invalidate();
}
public void SaveAs(string path)
public void SaveAsDrawing(string path)
{
using (var f = System.IO.File.CreateText(path))
{
@ -436,6 +476,77 @@ namespace SpiroNet.Wpf
}
}
public void OpenPlate(string path)
{
using (var f = System.IO.File.OpenText(path))
{
var plate = f.ReadToEnd();
ExecuteScript(plate);
}
}
public void SaveAsPlate(string path)
{
using (var f = System.IO.File.CreateText(path))
{
var plate = ToPlate(Shapes);
f.Write(plate);
}
}
private static string Format(double value)
{
return value.ToString(CultureInfo.GetCultureInfo("en-GB"));
}
public static string ToPlate(IList<PathShape> shapes)
{
var sb = new StringBuilder();
sb.AppendLine("(plate");
foreach (var shape in shapes)
{
foreach (var point in shape.Points)
{
switch (point.Type)
{
case SpiroPointType.Corner:
sb.AppendLine(string.Format(" (v {0} {1})", Format(point.X), Format(point.Y)));
break;
case SpiroPointType.G4:
sb.AppendLine(string.Format(" (o {0} {1})", Format(point.X), Format(point.Y)));
break;
case SpiroPointType.G2:
sb.AppendLine(string.Format(" (c {0} {1})", Format(point.X), Format(point.Y)));
break;
case SpiroPointType.Left:
sb.AppendLine(string.Format(" ([ {0} {1})", Format(point.X), Format(point.Y)));
break;
case SpiroPointType.Right:
sb.AppendLine(string.Format(" (] {0} {1})", Format(point.X), Format(point.Y)));
break;
case SpiroPointType.End:
sb.AppendLine(" (z)");
break;
case SpiroPointType.OpenContour:
sb.AppendLine(string.Format(" ({ {0} {1})", Format(point.X), Format(point.Y)));
break;
case SpiroPointType.EndOpenContour:
sb.AppendLine(string.Format(" (} {0} {1})", Format(point.X), Format(point.Y)));
break;
}
}
if (shape.IsClosed && !shape.IsTagged)
sb.AppendLine(" (z)");
}
sb.AppendLine(")");
return sb.ToString();
}
public void ExportAsSvg(string path)
{
using (var f = System.IO.File.CreateText(path))
@ -444,15 +555,23 @@ namespace SpiroNet.Wpf
var suffix = Environment.NewLine + " ";
sb.AppendLine("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
sb.AppendLine(string.Format("<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" width=\"{1}\" height=\"{0}\">", Width, Height));
sb.AppendLine(
string.Format(
"<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" width=\"{0}\" height=\"{1}\">",
Width,
Height));
foreach (var shape in Shapes)
{
sb.AppendLine(string.Format(" <path {0}",
shape.IsClosed ?
"style=\"fill-rule:nonzero;stroke:#000000;stroke-opacity:1;stroke-width:2;fill:#808080;fill-opacity:0.5\"" :
"style=\"fill-rule:nonzero;stroke:#000000;stroke-opacity:1;stroke-width:2;fill:none\""));
sb.AppendLine(string.Format(" d=\"{0}\"/>", Data[shape].Replace(Environment.NewLine, suffix)));
sb.AppendLine(
string.Format(
" <path style=\"{0};{1}\"",
shape.IsStroked ? "stroke:#000000;stroke-opacity:1;stroke-width:2" : "stroke:none",
shape.IsFilled ? "fill:#808080;fill-opacity:0.5" : "fill:none"));
sb.AppendLine(
string.Format(
" d=\"{0}\"/>",
Data[shape].Replace(Environment.NewLine, suffix)));
}
sb.AppendLine("</svg>");
@ -465,13 +584,15 @@ namespace SpiroNet.Wpf
{
return new PathShape()
{
IsStroked = true,
IsFilled = false,
IsClosed = false,
IsTagged = true,
Points = new ObservableCollection<SpiroControlPoint>()
};
}
private SpiroControlPoint ToPoint(SpiroPointType type, string x, string y)
private static SpiroControlPoint ToPoint(SpiroPointType type, string x, string y)
{
var point = new SpiroControlPoint();
point.X = double.Parse(x, CultureInfo.GetCultureInfo("en-GB").NumberFormat);
@ -487,13 +608,17 @@ namespace SpiroNet.Wpf
var newLine = Environment.NewLine.ToCharArray();
var separator = new char[] { ' ', '\t' };
var trim = new char[] { '(', ')' };
var options = StringSplitOptions.RemoveEmptyEntries;
var lines = script.Split(newLine, options).Select(x => x.Trim().Split(separator, options));
var lines = script.Split(newLine, options).Select(x => x.Trim().Trim(trim).Split(separator, options));
PathShape shape = null;
foreach (var line in lines)
{
if (line.Length == 0 || line[0] == "plate")
continue;
switch (line[0][0])
{
case 'v':

Просмотреть файл

@ -96,7 +96,10 @@ namespace SpiroNet.Wpf
if (Context.Data.TryGetValue(shape, out data) && !string.IsNullOrEmpty(data))
{
var geometry = Geometry.Parse(data);
dc.DrawGeometry(shape.IsClosed ? _geometryBrush : null, _geometryPen, geometry);
dc.DrawGeometry(
shape.IsFilled ? _geometryBrush : null,
shape.IsStroked ? _geometryPen : null,
geometry);
}
if (shape.Points != null)

Просмотреть файл

@ -116,7 +116,9 @@
Focusable="True"
FocusVisualStyle="{x:Null}">
<local:SpiroCanvas.InputBindings>
<KeyBinding Command="{Binding IsClosedCommand}" Key="S" Modifiers=""/>
<KeyBinding Command="{Binding IsStrokedCommand}" Key="K" Modifiers=""/>
<KeyBinding Command="{Binding IsFilledCommand}" Key="F" Modifiers=""/>
<KeyBinding Command="{Binding IsClosedCommand}" Key="D" Modifiers=""/>
<KeyBinding Command="{Binding IsTaggedCommand}" Key="T" Modifiers=""/>
<KeyBinding Command="{Binding PointTypeCommand}" CommandParameter="Corner" Key="V" Modifiers=""/>
<KeyBinding Command="{Binding PointTypeCommand}" CommandParameter="G4" Key="O" Modifiers=""/>
@ -141,7 +143,30 @@
</GroupBox>
<GroupBox Header="New Shape" Margin="4,2,4,2">
<StackPanel>
<CheckBox IsChecked="{Binding IsClosed}" VerticalContentAlignment="Center" Content="Is Closed 's'" Margin="1">
<CheckBox IsChecked="{Binding IsStroked}"
VerticalContentAlignment="Center"
Content="Is Stroked k"
Margin="1">
<CheckBox.ToolTip>
<StackPanel>
<TextBlock Text="Is stroked path shape" FontWeight="Bold"/>
</StackPanel>
</CheckBox.ToolTip>
</CheckBox>
<CheckBox IsChecked="{Binding IsFilled}"
VerticalContentAlignment="Center"
Content="Is Filled f"
Margin="1">
<CheckBox.ToolTip>
<StackPanel>
<TextBlock Text="Is filled path shape" FontWeight="Bold"/>
</StackPanel>
</CheckBox.ToolTip>
</CheckBox>
<CheckBox IsChecked="{Binding IsClosed}"
VerticalContentAlignment="Center"
Content="Is Closed d"
Margin="1">
<CheckBox.ToolTip>
<StackPanel>
<TextBlock Text="Is closed spiro shape" FontWeight="Bold"/>
@ -149,7 +174,10 @@
</StackPanel>
</CheckBox.ToolTip>
</CheckBox>
<CheckBox IsChecked="{Binding IsTagged}" VerticalContentAlignment="Center" Content="Is Tagged 't'" Margin="1">
<CheckBox IsChecked="{Binding IsTagged}"
VerticalContentAlignment="Center"
Content="Is Tagged t"
Margin="1">
<CheckBox.ToolTip>
<StackPanel>
<TextBlock Text="Is tagged spiro shape" FontWeight="Bold"/>
@ -165,7 +193,7 @@
<StackPanel>
<RadioButton IsChecked="{Binding Path=PointType, Converter={StaticResource EnumToBooleanConverterKey}, ConverterParameter={x:Static spiro:SpiroPointType.Corner}}"
VerticalContentAlignment="Center"
Content="Corner 'v'"
Content="Corner v"
Margin="1">
<RadioButton.ToolTip>
<StackPanel>
@ -176,7 +204,7 @@
</RadioButton>
<RadioButton IsChecked="{Binding Path=PointType, Converter={StaticResource EnumToBooleanConverterKey}, ConverterParameter={x:Static spiro:SpiroPointType.G4}}"
VerticalContentAlignment="Center"
Content="G4 'o'"
Content="G4 o"
Margin="1">
<RadioButton.ToolTip>
<StackPanel>
@ -187,7 +215,7 @@
</RadioButton>
<RadioButton IsChecked="{Binding Path=PointType, Converter={StaticResource EnumToBooleanConverterKey}, ConverterParameter={x:Static spiro:SpiroPointType.G2}}"
VerticalContentAlignment="Center"
Content="G2 'c'"
Content="G2 c"
Margin="1">
<RadioButton.ToolTip>
<StackPanel>
@ -198,7 +226,7 @@
</RadioButton>
<RadioButton IsChecked="{Binding Path=PointType, Converter={StaticResource EnumToBooleanConverterKey}, ConverterParameter={x:Static spiro:SpiroPointType.Left}}"
VerticalContentAlignment="Center"
Content="Left '['"
Content="Left ["
Margin="1">
<RadioButton.ToolTip>
<StackPanel>
@ -209,7 +237,7 @@
</RadioButton>
<RadioButton IsChecked="{Binding Path=PointType, Converter={StaticResource EnumToBooleanConverterKey}, ConverterParameter={x:Static spiro:SpiroPointType.Right}}"
VerticalContentAlignment="Center"
Content="Right ']'"
Content="Right ]"
Margin="1">
<RadioButton.ToolTip>
<StackPanel>
@ -221,7 +249,7 @@
</RadioButton>
<RadioButton IsChecked="{Binding Path=PointType, Converter={StaticResource EnumToBooleanConverterKey}, ConverterParameter={x:Static spiro:SpiroPointType.End}}"
VerticalContentAlignment="Center"
Content="End 'z'"
Content="End z"
Margin="1">
<RadioButton.ToolTip>
<StackPanel>
@ -232,7 +260,7 @@
</RadioButton>
<RadioButton IsChecked="{Binding Path=PointType, Converter={StaticResource EnumToBooleanConverterKey}, ConverterParameter={x:Static spiro:SpiroPointType.OpenContour}}"
VerticalContentAlignment="Center"
Content="OpenContour '{'"
Content="OpenContour {"
Margin="1">
<RadioButton.ToolTip>
<StackPanel>
@ -243,7 +271,7 @@
</RadioButton>
<RadioButton IsChecked="{Binding Path=PointType, Converter={StaticResource EnumToBooleanConverterKey}, ConverterParameter={x:Static spiro:SpiroPointType.EndOpenContour}}"
VerticalContentAlignment="Center"
Content="EndOpenContour '}'"
Content="EndOpenContour }"
Margin="1">
<RadioButton.ToolTip>
<StackPanel>
@ -257,17 +285,20 @@
<TextBlock Text="Mouse:" TextAlignment="Left" Foreground="Gray" Margin="4,0,4,0"/>
<TextBlock Text="Left -> Add Point" TextAlignment="Left" Foreground="Gray" Margin="4,0,4,0"/>
<TextBlock Text="Right -> Finish Shape" TextAlignment="Left" Foreground="Gray" Margin="4,0,4,0"/>
<TextBlock Text="Script:" TextAlignment="Left" Foreground="Black" Margin="4,4,4,0"/>
<TextBlock Text="Script/plate:" TextAlignment="Left" Foreground="Black" Margin="4,4,4,0"/>
<TextBox x:Name="scriptTextBox"
AcceptsReturn="True"
AcceptsTab="True"
IsReadOnly="False"
Height="240"
Height="180"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto"
Margin="4,0,4,0">
</TextBox>
<Button Content="Run" Command="{Binding ExecuteScriptCommand}" CommandParameter="{Binding ElementName=scriptTextBox, Path=Text}" Margin="4,4,4,0"/>
<Button Content="Run" Command="{Binding ExecuteScriptCommand}"
CommandParameter="{Binding ElementName=scriptTextBox, Path=Text}"
Margin="4,4,4,0">
</Button>
</StackPanel>
</Grid>
</UserControl>

Просмотреть файл

@ -63,6 +63,8 @@ namespace SpiroNet.Wpf
{
Width = 600,
Height = 600,
IsStroked = true,
IsFilled = false,
IsClosed = false,
IsTagged = false,
PointType = SpiroPointType.G4,
@ -77,6 +79,8 @@ namespace SpiroNet.Wpf
_context.SaveAsCommand = Command.Create(SaveAs);
_context.ExportAsSvgCommand = Command.Create(ExportAsSvg);
_context.ExitCommand = Command.Create(Exit);
_context.IsStrokedCommand = Command.Create(_context.ToggleIsStroked);
_context.IsFilledCommand = Command.Create(_context.ToggleIsFilled);
_context.IsClosedCommand = Command.Create(_context.ToggleIsClosed);
_context.IsTaggedCommand = Command.Create(_context.ToggleIsTagged);
_context.PointTypeCommand = Command<string>.Create(_context.TogglePointType);
@ -118,25 +122,47 @@ namespace SpiroNet.Wpf
private void Open()
{
var dlg = new Microsoft.Win32.OpenFileDialog();
dlg.Filter = "Spiro Files (*.spiro)|*.spiro|All Files (*.*)|*.*";
dlg.Filter = "Spiro Files (*.spiro)|*.spiro|Plate Files (*.plate)|*.plate|All Files (*.*)|*.*";
var result = dlg.ShowDialog();
if (result == true)
{
_context.Open(dlg.FileName);
switch (dlg.FilterIndex)
{
case 1:
_context.OpenDrawing(dlg.FileName);
break;
case 2:
_context.OpenPlate(dlg.FileName);
break;
default:
_context.OpenDrawing(dlg.FileName);
break;
}
}
}
private void SaveAs()
{
var dlg = new Microsoft.Win32.SaveFileDialog();
dlg.Filter = "Spiro Files (*.spiro)|*.spiro|All Files (*.*)|*.*";
dlg.Filter = "Spiro Files (*.spiro)|*.spiro|Plate Files (*.plate)|*.plate|All Files (*.*)|*.*";
dlg.FileName = "drawing.spiro";
var result = dlg.ShowDialog();
if (result == true)
{
_context.SaveAs(dlg.FileName);
switch (dlg.FilterIndex)
{
case 1:
_context.SaveAsDrawing(dlg.FileName);
break;
case 2:
_context.SaveAsPlate(dlg.FileName);
break;
default:
_context.SaveAsDrawing(dlg.FileName);
break;
}
}
}

Просмотреть файл

@ -29,10 +29,30 @@ namespace SpiroNet.Wpf
/// </summary>
public class PathShape : ObservableObject
{
private bool _isStroked;
private bool _isFilled;
private bool _isClosed;
private bool _isTagged;
private IList<SpiroControlPoint> _points;
/// <summary>
/// Is stroked path shape.
/// </summary>
public bool IsStroked
{
get { return _isStroked; }
set { Update(ref _isStroked, value); }
}
/// <summary>
/// Is filled path shape.
/// </summary>
public bool IsFilled
{
get { return _isFilled; }
set { Update(ref _isFilled, value); }
}
/// <summary>
/// Is closed spiro shape.
/// Whether points describe a closed (True) or open (False) contour.