Power Apps で横方向 Gallery 内のオブジェクトを任意の間隔で並べる方法

#はじめに
以前、Power Apps で楽譜を作成しようと思った際に、ひとつ大きな壁に当たりました。
それは、音符同士の間隔を「音符の長さ」の分だけ空ける必要がある、というルール。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405544/e5860b77-b708-5bf4-6b1e-5e4c63fa5d9c.png)
※このルールはあくまで基本ルールであり、実際の楽譜は様々なルールで作成されています。
[参考：音符のスペーシング - Finale](http://ws.finalemusic.jp/UserManuals/Finale25Mac/Content/Finale/Music_spacing.htm)
<br>
つまり、音符を配置する際には、1つ前の音符の長さ分空ける必要があります。
とある音符の配置場所は、1つ前の音符の長さに依存している、ということになります。

様々な楽譜に対応するためには、音符数の増減に柔軟に対応する必要があるため、Gallery を用いて…となるかと思います。
伸縮可能 Gallery を使えば何かできそうな気もしますが、横方向の Gallery には伸縮可能コントロールがなく、各項目の幅が均一のため、単純には実装できません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405544/776efbdd-2649-c4fa-6a58-63f03a4fdd5d.png)

そこで今回は、先人の知恵をお借りし、横方向の Gallery を用いて音符を自由に配置する方法について紹介します。

#先人の知恵と本手法のアイデア
本記事では、Gallery のTemplate Size = 0 の手法を利用します。
Gallery は基本的に様々なオブジェクトを Template Size で設定された間隔で等間隔に表示させることができますが、この Template Size を 0 （実際には1になる）に設定し、各オブジェクトの座標を Collection や数式を用いて動的に配置することで、例えば以下のように任意の位置に任意の数だけオブジェクトを配置できる、という手法です。
（以下の例は 各アイコンの X,Y 座標を Collection で定義し配置しています）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405544/f2cea1b6-35ea-b7ea-f68a-9b072ff2d12f.png)

Gallery の Template Size = 0 の手法については、@h-nagao さんの記事で分かりやすく解説されていますので、まずはこちらをご覧ください。

[わかれば簡単！ #PowerApps のTemplateSize=0の手法](https://qiita.com/h-nagao/items/c013c6274f28d74f0125)
<br>
さて、この方法を素直に用いれば実現はできるのですが、各音符の配置場所（X 座標）を1つ1つ定義するのは正直現実的ではありません。
つまり、こういうことです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405544/a4d2430c-608c-aa89-f67c-2bfc6973724b.png)

できるなら、各音符の長さ情報のみから、配置場所（X 座標）を決めたいですよね。
それができれば、途中で音符を削除したり入れ替えたりしても、容易に配置ができるようになります。

それなら、"自分より前の全ての音符の長さの合計"を座標情報として利用できるのではないかと考えました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405544/f09f1aaf-56bb-8bdf-260d-69740254ba5a.png)


#方法
上記の方法を確立するため、本記事では以下のように幅の異なる四角形を Gallery で並べる方法を紹介します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405544/e0f9bdfe-e7e3-b6f8-9f2d-006d4fa88784.png)

1. App の OnStart で、5つの四角形の長さを定義する Collection を以下のように定義します。
この方法では、IDは必須で、かつ音符の羅列順になっている必要があります。
記述したら、OnStart を実行しておきましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405544/330a576d-eab6-0983-446b-42a039bf9ca1.png)

    ```ruby:OnStart
    ClearCollect(colSampleData, 
    {ID: 1, Length: 150},
    {ID: 2, Length: 330},
    {ID: 3, Length: 220},
    {ID: 4, Length: 150},
    {ID: 5, Length: 80}
    );
    ```

2. 横方向（空）の Gallery を挿入します。
データ ソース（Items）に先ほど定義した Collection を指定します。
厳密に座標指定するために、テンプレートのパディング（TemplatePadding）は0にしておきましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405544/f5d11a58-6be9-8cd7-94d2-529e0bef207c.png)

3. Gallery 内に四角形を挿入します。
四角形の幅（Width）は Collection で定義した Length を設定します。
四角形の罫線や色は見やすいよう適宜設定してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405544/75a357f9-ab12-983b-ea07-3bad325bc75e.png)

4. 四角形の X に、以下の数式を記載します。
自分よりも ID の小さいアイテムの Length の合計を算出するものです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405544/b8da0e34-d800-598c-308d-a3cda63bd24b.png)

    ```ruby:X
    Sum(Filter(colSampleData, ID<ThisItem.ID),Length)
    ```

5. 最後に、Gallery のテンプレートのサイズ（TemplateSize）を 0 に設定して、完成です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405544/cbe73fca-8d3f-3d22-fce9-0b189bede546.png)
できました。

#まとめ
本記事で紹介した方法と、音の高さの処理を組み合わせることで、各音符の音の長さと音の高さの情報のみから簡単に楽譜を生成できるようになります。
![practiceapp.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405544/f38aa95f-03e1-f672-bc7c-6792059688f3.gif)

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">TimerとCollect関数を組み合わせて、ピアノに録音機能と楽譜生成機能を付けてみた。うまくいったとこをアップしたが、綺麗な楽譜になるように弾くのは結構難易度が高い。この手の専門ソフトは微妙なタッチのズレをどう補正しているのだろうか。<a href="https://twitter.com/hashtag/powerapps?src=hash&amp;ref_src=twsrc%5Etfw">#powerapps</a><a href="https://twitter.com/KeithWhatling?ref_src=twsrc%5Etfw">@KeithWhatling</a> Thank you for your idea!! <a href="https://t.co/UjOI6VRgW4">pic.twitter.com/UjOI6VRgW4</a></p>&mdash; Jun’ichi Kodama (@KodamaJn) <a href="https://twitter.com/KodamaJn/status/1072153838646259712?ref_src=twsrc%5Etfw">December 10, 2018</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<br>
ただ、いちいち Sum 関数で合計を計算しているため、動作はかなり重いです。
これでは長い曲が処理できない。。
もっといいアイデアをお持ちの方がいましたら、是非教えてください！！
<br>
これからは、欲しいアプリは欲しい人が作り、欲しいデータは欲しい人が集める時代です。
ハッピーになりたい人が自分の力でハッピーになれる世界へ。

何かのご参考になれば幸いです。