1. Qiita
  2. 投稿
  3. Ruby

OpalでElectronのアプリをつくる(その6)

  • 0
    いいね
  • 0
    コメント

    この記事は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.rbwrapper_class.rbはjsのクラスをラップするためのモジュールです。Nativeで置き換えることができそうです。
    fixuresもラッパーで使われているようです。
    observable.rbonメソッドを持つもののインタフェースのようです。これもNativeでできそうです。
    window.rbはElectronのウィンドウを表わすクラスのようですが、viewのrenderを呼んでいたりしてビューのフレームワークに依存していそうです。これは捨てます。

    結局、Nativeでラップしたクラスを作ればよいことになります。

    以前つくったexample程度は動くようしようと思います。

    app/main.rb
    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モジュールをつくります。

    lib/opal/electron.rb
    require 'native'
    
    module Electron
      class << self
        def app
          native.app
        end
    
        def native
          @native ||= Native(`require('electron')`)
        end
      end
    end
    

    ネイティブのElectronオブジェクトからappを取得できるようにします。

    つぎはBrowserWindow

    lib/opal/electron/browser_window.rb
    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
    

    ネイティブのBrowserWindownewします。
    ここでちょっとしたテクニックでjsというモジュールを使っています。

    http://opalrb.org/docs/guides/v0.10.3/compiled_ruby.html

    使いかたはここらへんにあります。

    これでmain.rbが次のように書けるようになりました。

    app/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の実装について書こうかと思います。それでは〜