Electron に Mac タッチバー API が実装された
個人的に気になっていた Electron のタッチバーサポートがついに master にマージされました.
実装は下記の PR で行われ,@MarshallOfSound さんの初期実装と @kevinsawicki さんのブラッシュアップで実装されました.
https://github.com/electron/electron/issues/8095
まだリリースされていないですが,待てなかったので master ブランチの実装を試してみました.
追記(2017/3/8): v1.6.3 beta としてリリースされました.
Electron の master ブランチをビルドする
ビルドの仕方はドキュメントにまとめられています. 再配布せず手元で試すだけであれば面倒そうな「macOS SDK」のセクションは無視してしまって大丈夫です.
# リポジトリを取得 $ git clone https://github.com/electron/electron && cd electron/ # ビルドに必要な依存関係パッケージの取得 $ ./script/bootstrap.py -v # ビルド $ ./script/build.py
ビルドにはそれなりに時間がかかります.out/R
にリリースビルドの Electron.app
が,out/D
にデバッグビルドの Electron.app
が生成されます.
Touchbar API
タッチバーはメインプロセスから制御することができます.レンダラプロセスからは IPC 経由でのアクセスになりそうです. macOS 10.12.1 以降のタッチバー搭載 MacBook Pro で利用できるようです
タッチバーの UI パーツにはいくつかの種類があり,各パーツごとの class と,それらをまとめる class が提供されています.
TouchBarButton
: アイコンとテキストが置けるボタンですTouchBarColorPicker
: カラーピッカーですTouchBarGroup
: 複数の UI パーツを1つのグループとして配置できますTouchBarLabel
: テキストを表示できるラベルですTouchBarPopover
: アイコンとラベルとキャンセルボタンが表示できる,タッチバーに出るダイアログボックス的な UI ですTouchBarSlider
: 音量などに使えるスライダーですTouchBarSpacer
: タッチバーのアイテムとアイテムの間にスペースを開けることができます.開けるスペースはsmall
,large
,flexible
(スペースを取れるだけ取る) の中から選べますTouchBar
:TouchBar
は上記 Touchbar の UI パーツを並べてタッチバーインスタンスを生成できます
タッチバーインスタンスは BrowserWindow
の setTouchbar()
メソッドによってセットできます.セットされると即座にタッチバーが表示されます.また,setTouchbar
メソッドに null
を与えることでタッチバーを消すことができます.
サンプルアプリ
ドキュメントにのっているサンプルアプリを動かしてみます.ドキュメントにはコード片のみなので,動くコードを下記に置いてみました.
サンプルアプリではタッチバー上でスロットを回すことができます.
エントリポイントである main.js
は下記の通りです.
const path = require('path') const {app, BrowserWindow, TouchBar} = require('electron') // 必要なタッチバーの UI パーツをインポートする const {TouchBarLabel, TouchBarButton, TouchBarSpacer} = TouchBar let spinning = false // スロットの各リールの文字列を表示するラベル3つ const reel1 = new TouchBarLabel() const reel2 = new TouchBarLabel() const reel3 = new TouchBarLabel() // スロットを回した結果を表示するラベル const result = new TouchBarLabel() // 'Spin' ボタン const spin = new TouchBarButton({ label: '🎰 Spin', // ボタンのテキスト.ここでは絵文字だけどアイコンも置けるはず… backgroundColor: '#7851A9', click: () => { // スロットが回っている間はクリックを無視する if (spinning) { return } // スロットを回す処理 spinning = true result.label = '' let timeout = 10 const spinLength = 4 * 1000 // 4 seconds const startTime = Date.now() // クリックされてから4秒間スロットを回す const spinReels = () => { // スロットのリールを更新する.止まった時のリールが結果になる updateReels() if ((Date.now() - startTime) >= spinLength) { finishSpin() } else { // 1.1倍ずつスロットを遅くしていく(慣性っぽさ) timeout *= 1.1 setTimeout(spinReels, timeout) } } spinReels() } }) // ランダムに絵柄を1つ選ぶ関数 const getRandomValue = () => { const values = ['🍒', '💎', '7️⃣', '🍊', '🔔', '⭐', '🍇', '🍀'] return values[Math.floor(Math.random() * values.length)] } // 3つのリールを更新 const updateReels = () => { reel1.label = getRandomValue() reel2.label = getRandomValue() reel3.label = getRandomValue() } const finishSpin = () => { // Set を使って重複を省き,残った要素数で絵柄がいくつ合ったかをチェックする const uniqueValues = new Set([reel1.label, reel2.label, reel3.label]).size if (uniqueValues === 1) { // すべての絵柄が揃ったとき:大当たり! result.label = '💰 Jackpot!' result.textColor = '#FDFF00' } else if (uniqueValues === 2) { // 3つ中2つのリールが同じ絵柄だったとき:当たり result.label = '😍 Winner!' result.textColor = '#FDFF00' } else { // 絵柄がまったく揃わなかったとき:はずれ result.label = '🙁 Spin Again' result.textColor = null } spinning = false } // [ボタン] [r1] [r2] [r3] [result] // // のように配置.配列に入れたパーツが入れた順にタッチバーに表示される const touchBar = new TouchBar([ spin, new TouchBarSpacer({size: 'large'}), reel1, new TouchBarSpacer({size: 'small'}), reel2, new TouchBarSpacer({size: 'small'}), reel3, new TouchBarSpacer({size: 'large'}), result ]) let window app.once('ready', () => { window = new BrowserWindow({ width: 200, height: 200 }) window.loadURL(`file://${path.join(__dirname, '/index.html')}`) // ブラウザウィンドウにタッチバーをセットする. // このタイミングでタッチバーにスロットマシンが表示される window.setTouchBar(touchBar) }) // 全てのウィンドウが閉じたときアプリを閉じる app.on('window-all-closed', () => { app.quit() })
まとめ
ついに Electron アプリでもタッチバーにアクセスできるようになりました. まだ入ったところなので多少バグなどがあるかもしれませんが,面白い機能なので是非自分がつくっているアプリでも活用を考えたいと思います. 何事も無ければ次リリースに含まれると思うので,今週後半か来週あたりには v1.6 系で使えるようになるのではと思います.