XAML の Path の表示位置やサイズを調整するツールを作りました
Metro Studio で出力される Path だと AppBarButton の Icon として利用しづらい
・・・ないものは作るしかない!ということで WPF で正規化するツールを作ってみました
こんな感じで右上の窓に Path の Data プロパティの文字列を張り付けてサイズや余白を調整すると、右上の Data 文字列が更新されます
調整が終わったら、「Copy」ボタンでクリップボードにコピーして XAML に埋め込めば OK というわけです
ソースは GitHub にアップしてます
tatsuji-kuroyanagi/PathNormalizeTool · GitHub
ちなみに Path の Data プロパティは文字列を直接設定することができません
なので次のように Data 文字列を解析して Geometry インスタンスを生成しています
/// <summary> /// Path Data /// </summary> public string PathData { get { return this.pathData; } set { this.Set<string>("PathData", ref this.pathData, value); this.Geometry = Geometry.Parse(this.pathData); this.Width = (this.Geometry.Bounds.Right - this.Geometry.Bounds.Left); this.Height = (this.Geometry.Bounds.Bottom - this.Geometry.Bounds.Top); this.UpdatePathData(); this.RaisePropertyChanged("PathData"); this.RaisePropertyChanged("IsInputted"); } }
残念ながら Geometry.Parse() メソッドは Windows ストアアプリにはないみたいです;
あとは Width や Height、Margin の入力値に応じて、こんな感じで Segment をごにょごにょすればできました!
/// <summary> /// Path の整形 /// </summary> public void UpdatePathData() { try { if (this.Geometry == null) { return; } var pathGeometory = (this.Geometry.Clone() as StreamGeometry).GetFlattenedPathGeometry(); var scaled = new PathGeometry(); double scaleX = (this.Geometry.Bounds.Right - this.Geometry.Bounds.Left) / this.Width; double scaleY = (this.Geometry.Bounds.Bottom - this.Geometry.Bounds.Top) / this.Height; foreach (var figure in pathGeometory.Figures) { var newFigure = new PathFigure(); newFigure.StartPoint = new Point( ((figure.StartPoint.X - this.Geometry.Bounds.Left) / scaleX) + this.Left, ((figure.StartPoint.Y - this.Geometry.Bounds.Top) / scaleY) + this.Top ); foreach (PolyLineSegment segment in figure.Segments) { var newSegment = new PolyLineSegment(); foreach (var point in segment.Points) { newSegment.Points.Add(new Point( ((point.X - this.Geometry.Bounds.Left) / scaleX) + this.Left, ((point.Y - this.Geometry.Bounds.Top) / scaleY) + this.Top )); } newFigure.Segments.Add(newSegment); } scaled.Figures.Add(newFigure); } scaled.Freeze(); this.pathData = scaled.ToString(); this.RaisePropertyChanged("PathData"); this.PathGeometry = scaled; } catch (Exception) { } }
大量の正規化は難しいですがちょっとした調整だったら使える・・・ですかね?