見た目とウィンドウ
すべての要素が取るキーワード、配色、そしてウィンドウ自身が持ってくるもの。
すべての要素が取るキーワード
次の 15 の性質は、どの要素でも同じ意味を持ち、どれもメソッドとして呼べます。
| メソッド | 型 | 働き |
|---|---|---|
Width(v), Height(v) |
float64 | 固定の大きさ。0 でもそのまま書かれる |
MinWidth(v), MaxWidth(v) |
float64 | 大きさの下限と上限 |
Disabled(v) |
bool | 操作を受け付けず、その見た目で描かれる |
Theme(v) |
string | 下にある要素が色の名前を引く配色。"dark" か "light" |
Animate(ms), Easing(v) |
float64, string | 変化にかける時間と、その曲がり方("out"、"inOut") |
Enter(v), Exit(v) |
bool | 現れるとき、消えるときの動き |
ColSpan(v), RowSpan(v) |
int | グリッドの列や行をいくつ分またぐか |
Role(v), A11yLabel(v) |
string | 読み上げに伝える内容 |
Tooltip(v) |
string | ポインタを合わせたときに出る文字 |
同じ名前をもともと自分の意味で持っている要素では、要素側の意味がそのまま通ります。
Button の Width はボタン自身の幅で、ボタンはその幅で描かれます。
Column の Width は、中身を囲む箱の幅です。
ラベルがそのまま読み上げの名前になる要素(Checkbox、Switch、Progress)は、A11yLabel を断ります。
与えるべき二つ目の名前がないからです。
テーマとアニメーション
色は 16 進の値か、エンジンが持つ色の名前("accent"、"panel"、"text"、"textDim")です。
名前で書いた色は、上にあるいちばん近い Theme の配色で決まります。
だからメソッド一つで、パネル全体の色が切り替わります。
package main
import (
"fmt"
. "github.com/i2y/yokan/gomamochi"
)
func key(b *ButtonEl) *ButtonEl { return b.Background("#313244").HoverBackground("#45475a") }
type Styled struct {
mode string
n int
}
func (s *Styled) flip() {
if s.mode == "dark" {
s.mode = "light"
} else {
s.mode = "dark"
}
}
func (s *Styled) View() Element {
return Column(
Text(fmt.Sprintf("n=%d", s.n)).Size(18).Color("accent"),
Row(
key(Button("+1")).OnClick(func() { s.n += 1 }),
key(Button("flip")).Background("#fab387").OnClick(func() { s.flip() }),
).Spacing(6),
).Spacing(8).Padding(12).Background("panel").Theme(s.mode)
}
func main() {
Run(&Styled{mode: "dark"}, Title("styled"))
}
見た目を一か所にまとめるには、渡された要素すべてに同じ性質を付ける関数を書きます。
上の key がそれです。
返るのは元の要素の型なので、そのあともメソッドをつなげられます。
要素に Animate(120).Easing("out") と書くと、その要素は変化のたびに 120 ミリ秒かけてなめらかに動きます。
現れるときと消えるときにも、Enter と Exit で同じ動きがつきます。
ウィンドウまわり
Run はアプリとそのオプションを取ります。
オプションは Title、Size(width, height)、それにウィンドウの縁とアプリのツリーのあいだの余白である Padding です。
Quit() は、エンジンの次のフレームでウィンドウを閉じます。
ウィンドウなしの実行ではこれが効かないので、スクリプトは最後まで走ります。
並べたり覆ったりする要素は、次のとおりです。
Grid は子要素を Columns で決めた数の列に並べ、GridCell(child).ColSpan(2) はその列をまたぎます。
Stack は子要素を重ねて置きます。
ScrollView と HScrollView はスクロールする領域です。
Modal は、Open のあいだ、ウィンドウのほかの部分に重なって出るパネルです。
Spacer は親要素に余っている場所を取り、Divider は罫線を引き、Link はページを開き、Spinner と Progress は処理中であることを示し、Image と Svg はファイルを表示します。
package main
import (
"fmt"
. "github.com/i2y/yokan/gomamochi"
)
type Panels struct {
open bool
}
func (p *Panels) View() Element {
var lines []Element
for n := 1; n <= 12; n++ {
lines = append(lines, Text(fmt.Sprintf("line %d", n)))
}
return Stack(
Column(
Row(Text("Panels").Size(18), Spacer(), Spinner().Size(14)).Spacing(8),
Grid(Text("one"), Text("two"), GridCell(Text("across both").Align("center")).ColSpan(2)).Columns(2).Spacing(6),
ScrollView(Column(lines...).Spacing(2)).Height(90),
Button("about").OnClick(func() { p.open = true }),
).Spacing(10).Padding(14),
Modal(
Column(
Text("A panel over the rest of it.").Size(14),
Button("close").OnClick(func() { p.open = false }),
).Spacing(8).Padding(12).Background("panel"),
).Open(p.open),
)
}
func main() {
Run(&Panels{}, Title("panels"), Size(420, 360))
}