はじめに
スリントのアドベントカレンダーもついに第二週目に突入しました。せっかくの2週枠1日目だというのに、一昨日から風邪っぽい感じで記事が遅刻ですいません。
昨日は、@task_jp さんの「Raspbeery Pi5 でslintを動かす」でした。実践的な紹介をしてもらえていると試せてより楽しくいけますよね。
幸い新しい方のエントリーも入ってます。入門とか言って小出しにドキュメントの内容をもう少しわかりやすくならないかなぁと思いながら日本語で書き下していますが、その先は書きたいという人が現れても大丈夫です。こういうのは早いもの勝ちです。遠慮とかなしにどんどん記事を埋めてください。
本日のお題
先日はSlintの基本となるモジュール・コンポーネント・エレメント周りについて記載しました。そこで、本日は実際の構文について触れていきたいと思います。
Slint言語入門
識別子
識別子はコンポーネント名、エレメント名、プロパティ名などにつける名前に当たります。他の要素と区別するための重要なものですが、利用できる文字などに制限があります。
識別子はアンダースコア(_)、文字(a-zA-Z)はじまりで、文字、数字(0-9)、アンダースコア、ダッシュ(-)を使えるとドキュメントされています。ダッシュと記載されていますが、エヌダッシュではなく、キーボードに用意のあるいわゆるハイフンです。
なお注意事項として識別子の-と_は正規化されて同じと判断されるためfoo_barとfoo-barは同じ識別子として扱われるそうです。
型
すべてのプロパティは型をもっています。
プリミティブ型
型 | 概要 | Unit | 初期値 |
---|---|---|---|
angle | 角度 | deg,rad,grad,turn | 0 deg |
bool | 真偽値(true or false) | なし | false |
brush | ブラシ。色またはグラデーション | なし | 透明色 |
color | 色 #RRGGBBAA or #RGB or CSS color | なし | 透明色 |
duration | アニメーション期間 | ms,s | 0ms |
easing | アニメーション緩和曲線。 | なし | linear |
float | 符号付き32bit 浮動小数点数。%指定時は100で割った数に変換 | なし、% | 0.0 |
image | ロード済み画像 | 空 | |
int | 符号付き整数 | 0 | |
length | 座標とサイズに利用される | px, pt, in, mm, cm | 0px |
percent | 符号付き32bit | % | 0% |
phyical-length | 物理ピクセル量 | phx | 0phx |
relative-font-size | 相対フォント係数 | rem | 0rem |
string | UTF-8エンコード文字列 | "" |
プリミティブ型は事前に言語として定義された型です。Slintでは型によってはUnitを明示する必要があることに留意していください。詳細は、実際の利用とともに今後解説していきます。
構造体
structキーワードを使い構造体を定義してユーザー型として利用できます。structに続く識別子を型名として利用します。
export struct Player {
name: string,
score: int,
}
export component Example {
in-out property<Player> player: { name: "Foo", score: 100 };
}
初期値はそれぞれのフィールドの型の初期値となります。
また、識別子を持たない無名構造体を定義することもできます。
export component Example {
in-out property<{name: string, score: int}> player: { name: "Foo", score: 100 };
in-out property<{a: int, }> foo: { a: 3 };
}
列挙型
enumキーワードを使い列挙型を定義して、特定の値をもつデータ型を宣言できます。列挙型を状態や選択肢に使うことでコードの可読性を高め、意図しない値の使用を防ぐことができます。列挙型の値は、型名.値名という記述で利用できます。コールバックの戻り値や列挙型バインディングでは列挙型名は省略できます。
export enum CardSuit { clubs, diamonds, hearts, spade }
export component Example {
in-out property<CardSuit> card: spade;
out property<bool> is-clubs: card == CardSuit.clubs;
}
初期値は、列挙された最初の値となります。上記では、CardSuit.clubsが初期値です。
配列
型名を[]記号で囲うと配列を定義できます。
property<[int]> list-of-int: [1, 2, 3];
property<[{a: int, b: string}]> list-of-structs: [{ a: 1, b: "hello" }, { a: 2, b: "world" }];
配列操作
言語として、以下の操作がサポートされています。
.lengthプロパティ
配列の要素数を取得するために使用します。
Text { text: "length: " + list-of-int.length; }
indexアクセス
一般的な言語同様、index演算子[]を使って個々の要素にアクセスできます。
Text { text: "value: " + list-of-int[0]; }
なお、範囲外の値にアクセスした場合は初期値になります。エラーではないので留意が必要です。
また、in-out指定されているプロパティであれば、ハンドラなどで値を更新することが可能です。
in-out property<[int]> list-of-int: [1, 2, 3];
on_button_clicked => {
list-of-int = [4, 5, 6];
};
型変換
Slintは、異なる型間の変換が用意されています。UI記述を堅牢にするためには、明示的な変換が必要ですが、一部の型間については利便性のため暗黙の型変換がサポートされています。
- 暗黙の変換
- int から float
- float から int(切り捨て)
- int から string
- float から string
- ピクセル比がわかっている場合のphysical-length, relative-font-size, length間相互変換
- 同一プロパティを含み、その型が変換可能な構造体間で、ソース側に不足プロパティ・余分なプロパティの双方が含まれない場合
- リテラルから関連づいたUnitをもつ型
- 配列リテラルから要素型が変換可能な配列
- 演算による変換
- 数値単位/1単位 から 数値 (15px/1px -> 15)
- 数値*1単位 から 数値単位 (15 * 1px -> 15px)
- 関数による変換
- string.to-float() から float
- string.is-float() から bool
まとめ
本日は、ほぼドキュメントそのまま、識別子とプロパティの定義・利用時に必要な型に関する基本構文についてざっくり解説しました。いやぁ、構文まわり全部もう少しわかりやすく例をあげつつ書いた上でQtの記事もと思ってたのですが、体調が悪いままで昨日に引き続きほとんど寝て過ごしてました。歳はとりたくないものですねぇ。
まぁ、まだカレンダーは続きますしどこかで埋め合わせします。
明日というか今日は、@task_jpさんの「PSD ファイルをロードする Qt 6 のモジュールを作りました」です。PSDからQMLとSlint等へ変換するツールの紹介ですので楽しみに待ちましょう。
風邪とかもろもろ流行る季節ですので、みなさんは体調管理をしっかりして体調崩さずよいクリスマスに向けてがんばりましょう。いま体調崩してる人は暖かくして寝て早く治しましょうね(え、お前がいうなって…すいません)。