この記事はOpal Advent Calendar 2016の22日目の投稿として書いています。
今日はElectronのAPIをなんとかします。
ElectronのAPIラッパーはelectron_opalのopalディレクトリにあります。
electron_opal/
├── lib/
└── opal/
├── electron/
├── browser_process.rb
└── main_process.rb
ElectronにはMain ProcessとRender Process(Browser Process)があるので、それぞれに必要なファイルをロードするように、ファイルが分かれています。
opal/electronの下に実際に読みこまれるファイルが入っています。
opal/electron/
├── app.rb
├── main_process_modules.rb
├── renderer_process_modules.rb
├── both_process_modules.rb
├── browser_window.rb
├── fixtures/
│ ├── array.rb
│ ├── hash.rb
│ └── kernel.rb
├── fixtures.rb
├── observable.rb
├── window.rb
├── wrapper.rb
└── wrapper_class.rb
wrapper.rbとwrapper_class.rbはjsのクラスをラップするためのモジュールです。Native
で置き換えることができそうです。
fixuresもラッパーで使われているようです。
observable.rbはon
メソッドを持つもののインタフェースのようです。これもNative
でできそうです。
window.rbはElectronのウィンドウを表わすクラスのようですが、viewのrender
を呼んでいたりしてビューのフレームワークに依存していそうです。これは捨てます。
結局、Native
でラップしたクラスを作ればよいことになります。
以前つくったexample程度は動くようしようと思います。
require 'opal'
require 'native'
electron = Native(`require('electron')`)
app = electron.app
app.on('window-all-closed') { app.quit unless $$.process.platform == 'darwin' }
app.on('ready') do
main_window = Native(`new electron.native.BrowserWindow({width: 800, height: 600})`)
main_window.loadURL("file://#{`__dirname`}/main_window.html")
main_window.on('closed') { main_window = nil }
end
まずはElectronモジュールをつくります。
require 'native'
module Electron
class << self
def app
native.app
end
def native
@native ||= Native(`require('electron')`)
end
end
end
ネイティブのElectron
オブジェクトからapp
を取得できるようにします。
つぎはBrowserWindow
require 'electron'
require 'js'
module Electron
class BrowserWindow
include Native
def initialize(name, params = {}, debug: false)
`var { BrowserWindow } = require('electron')`
@native = JS.new(`BrowserWindow`, params)
@native.JS.loadURL("file://#{`__dirname`}/main_window.html")
@native.JS[:webContents].JS.openDevTools if debug
end
alias_native :on
end
end
ネイティブのBrowserWindow
をnew
します。
ここでちょっとしたテクニックでjs
というモジュールを使っています。
使いかたはここらへんにあります。
これでmain.rbが次のように書けるようになりました。
require 'opal'
require 'electron/browser_window'
app = Electron.app
app.on('window-all-closed') { app.quit }
app.on('ready') do
main_window = Electron::BrowserWindow.new('main_window', {width: 800, height: 600}, debug: true)
main_window.on('closed') { main_window = nil }
end
今回はこれくらいで。さてもうすこし本格的なElectronのプログラムを書いてみたくなりますが、残り回数も少ないので次回は、これまで何度も出てきたNative
の実装について書こうかと思います。それでは〜