#author("2023-05-02T15:58:01+09:00","default:kyo-in","kyo-in") #author("2023-06-19T10:33:07+09:00","default:kyo-in","kyo-in") **ストローク [#v260e47d] 課題:ストロークの描画を実装する. #ref(./drawstroke.gif,50%); **線の構成要素 [#o1dad5d8] UWPではGUIを構成する部品の子として,Shapeクラスを追加することで図形を描画できる. 線は,Shapeクラスを継承しているLineクラス,もしくはPathクラスを使用するが,ここではPathクラスを使用する. Pathクラスでは,線の色や太さを設定し,Dataメンバに線の形状が入ったPathGeometryを与える. PathGeometryクラスは,円弧(Arcs),曲線(Curves),直線(Lines)など,種類の異なる頂点ベースで与えられる複数の形状データ(PathFigure)をまとめるものである.実際にはFiguresメンバにPathFigureインスタンスを与える. PathFigureは複数のSegmentで構成された図形を表すクラスで,開始点や図形の閉じなどの設定を行う.実際にはSegmentsメンバにSegmentを継承したBezierSegment, LineSegment, PolyBezierSegment, PolyLineSegment, PolyQuadraticBezierSegment, QuadraticBezierSegmentなどいずれかのSegmentインスタンスを追加する. 今回,ストロークは複数点を単純に結んだ線となるため,PolyLineSegmentを使用する. PolyLineSegmentのPointsメンバに座標を記した複数個のPointをPointsメンバに与えることで,それらを直線で結んだ線を描画する.Pointsメンバの操作で点の増減があった場合はリアルタイムに画面に反映される. #ref(./path.png,50%); //プログラム上部の //using System.IO; をコメントアウト //using Windows.UI; を追加 //using Windows.UI.Xaml.Shapes; を追加 PathFigure myPathFigure = new PathFigure(); myPathFigure.StartPoint = new Point(10, 50); LineSegment myLineSegment = new LineSegment(); myLineSegment.Point = new Point(200, 70); PathSegmentCollection myPathSegmentCollection = new PathSegmentCollection(); myPathSegmentCollection.Add(myLineSegment); myPathFigure.Segments = myPathSegmentCollection; PathFigureCollection myPathFigureCollection = new PathFigureCollection(); myPathFigureCollection.Add(myPathFigure); PathGeometry myPathGeometry = new PathGeometry(); myPathGeometry.Figures = myPathFigureCollection; Path myPath = new Path(); myPath.Stroke = new SolidColorBrush(Color.FromArgb(255, 0, 0, 0)); myPath.StrokeThickness = 1; myPath.Data = myPathGeometry; MainCanvas.Children.Add(myPath); -図形の描画 - Windows UWP applications~ https://docs.microsoft.com/ja-jp/windows/uwp/design/controls-and-patterns/shapes **手順 [#j09d98fb] 例外的な処理を考慮しなければ, 描画中のPathクラスを保持するメンバ変数(仮にdrawingStrokeと名付ける)を追加し, +PointerPressedイベント:drawingStroke(Pathクラス)に必要なクラスインスタンス一式を生成 +PointerMovedイベント:drawingStrokeがnullでなければ,ストローク描画中であるから現在のマウス座標をPolyLineSegmentのPointsメンバにAddする +PointerReleasedイベント:drawingStrokeがnullでなければ,描き終わったことを示すためnullにしておく 実際にはストローク描画途中(マウスボタンが押されたまま)でウインドウのフォーカスが外れた,マウスカーソルがウインドウ外に出た場合など,PointerReleasedイベントが起きずにストローク描画を終了しなければいけない場面もある. ***PathクラスからPolyLineSegmentへアクセスする [#b071af12] Windows.UI.Xaml.Shapes.Pathから点群,PolyLineSegmentを取り出すメソッド(エラー処理なし) private PolyLineSegment GetPolyLineSegment(Windows.UI.Xaml.Shapes.Path src) { var pathgeom = (PathGeometry)src.Data; var pathfig = pathgeom.Figures[0]; return (PolyLineSegment)pathfig.Segments[0]; } **メッセージ表示 [#f7e22d1a] テンプレートプログラムではデフォルトでメッセージ表示用のTextBlockが用意されている. 以下が引数に指定された文字列を表示するメソッド例となる.StatusBlockScroll.ChangeViewメソッドはメッセージを追加された文字列位置に合わせるため,スクロールを最下段に移動させるためのものである. 1.MainPageXamlのScrollViewerに名前を付ける. <ScrollViewer VerticalScrollMode="Auto" VerticalScrollBarVisibility="Auto" MaxHeight="200" HorizontalAlignment="Stretch" Height="117" Margin="0,0,0,0" VerticalAlignment="Stretch"> ↓ <ScrollViewer x:Name="StatusBlockScroll" VerticalScrollMode="Auto" VerticalScrollBarVisibility="Auto" MaxHeight="200" HorizontalAlignment="Stretch" Height="117" Margin="0,0,0,0" VerticalAlignment="Stretch"> 2.以下のメソッドをMainPage.xaml.csに追加 private void AddMessage(string str) { StatusBlock.Text += str + System.Environment.NewLine; StatusBlockScroll.ChangeView(0, StatusBlockScroll.ScrollableHeight, StatusBlockScroll.ZoomFactor, false); } **課題提出方法 [#r54a0cd6] 招待されているBoxアップロードフォルダ「情報メディア基礎ゼミ(森谷)」の「第2回」へ,完成させた課題のソリューションフォルダをZIP圧縮し,ファイルを以下の名前でアップロードしてください. ファイル名:XXFIXXX_2nd.zip(例:18FI999_2nd.zip) ''提出締め切り:5月12日(金) 23:59'' ''提出締め切り:6月23日(金) 23:59'' BOXアップロードフォルダの招待メールが来ていない方は森谷までメール連絡ください.