NimのGUIフレームワーク、nimxに入門してみる
タイトル通りNimのGUIフレームワーク、nimxに入門した話です。 この記事は Nim Advent Calendar 2018 の20日目の記事として登録させていただいています。 初アドベントカレンダーですね。
nimxとは
nimxとは、Nimのクロスプラットフォーム対応のGUIフレームワークです。 GitHub: https://github.com/yglukhov/nimx
nakeを用いてiOS, Android, MacOS, Windows, Linux, JS, Asm.jsに対応したビルドが可能です。(webの知識があれなのでJSに関しては公式ドキュメントの参照を推奨します)
この記事について
さて、この記事ではnimxの導入から実際にビルドしてみる手順までをまとめようかと思いますが、僕の実行した環境は以下です。
macOS Mojave
Nim 0.19.0
nimx 0.1
導入
nimxのインストールなどは基本的にGitHubリポジトリのドキュメントに書いてあることを実行すればokなのですが、念のためコマンドを示しておきます。
インストールはnimbleから
$ nimble install nimx
もしnimbleが入っていないならば
$ git clone https://github.com/nim-lang/nimble.git $ cd nimble $ nim c src/nimble $ src/nimble install
を実行してから上のコマンドを実行してください。*1
僕は大丈夫だったのですが、どうやらインストールでエラーがでたみたいな記事も拝見したので、もしインストールで何かつっかかるようでしたらこちらの記事なんかが参考になるかもしれません
実行してみる
nimxをインストールしたら実際にhello world appを実行してみました。
ドキュメントに書いてある通りにhelloworld.nim
を作成し、$ nim c -r --threads:on helloworld
で実行できるはずです。
helloworld.nim
のコードは以下です。
import nimx / [ window, layout, button, text_field ] runApplication: let w = newWindow(newRect(50, 50, 500, 150)) w.makeLayout: # DSL follows - Label as greetingLabel: # Add a view of type Label to the window. Create a local reference to it named greetingLabel. center == super # center point of the label should be equal to center point of superview width == 300 # width should be 300 points height == 15 # well, this should be obvious now text: "Press the Greet button to see the greeting" # property "text" should be set to whatever the label should display - Button: # Add a view of type Button. We're not referring to it so it's anonymous. centerX == super # center horizontally top == prev.bottom + 5 # the button should be lower than the label by 5 points width == 100 height == 25 title: "Greet" onAction: greetingLabel.text = "Hello, world!"
macでしたら以下のようなウインドウが表示されるのではないでしょうか。(画像はnimx/doc/hello-world-app.pngより)
コードと表示されたウインドウとを見比べてもらえればコンテンツのwidth
やheight
、text
の設定についてはわかると思いますが、super
やprev
については以下のような意味を持っています*2
super
-> そのviewを持っているview (= 親view)prev
-> 直前に置かれた、同じ親をもつview
nakeでビルド
nimxでつくったGUIを実際に様々なプラットフォーム向けにビルドするにはnakeを使います。
nakeはNimのビルド時のタスクを記述するためのビルドツールです。 導入が済んでいない場合はこれもnimbleからインストールできます。
$ nimble update $ nimble install nake
試しに先ほどのhello world appをnakeを使ってビルドしてみましょう。
まず、適当に空のディレクトリを作成してそこに先ほどのhelloworld.nimを移動し、新たにnakefile.nim
を作成してください。
今回はnakefile.nim
の中身は
import nimx/naketools
の一行のみで大丈夫です。
これによって実行されるファイルがmain.nim
に指定されるので、helloworld.nim
を main.nim
に名前を変更しておきます。
ここまで済んだら$ nake
を実行するだけなのですが、僕の環境ではここでエラーが。。
Hint: xmltree [Processing] Hint: xmlparser [Processing] Hint: parsexml [Processing] ../../.nimble/pkgs/nimx-0.1/nimx/naketools.nim(423, 17) Error: undeclared identifier: 'stripLineEnd'
ふむ?ということでundeclaredですよ〜とのことのstripLineEnd
について調べてみると、これはNimの標準ライブラリに含まれているプロシージャのはずなのですが、なぜかエラーが出ている。
ということでNimのstrutilsのコードを見てみるとstripLineEnd
はまだmasterにマージされていない様子でした。
そこで、自分の~/.nimble/pkgs/nimx-0.1/nimx/naketools.nim
の423行目のstripLineEnd(result)
を、Nimの適当なブランチ*3のstripLineEnd()
の実装内容を踏まえて、
if result.len > 0: case result[^1] of '\n': if result.len > 1 and result[^2] == '\r': result.setLen result.len-2 else: result.setLen result.len-1 of '\r', '\v', '\f': result.setLen result.len-1 else: discard
のように変更したところ、$ nim c -r --threads:on helloworld
と同じように実行できました。
各プラットフォーム向けのビルドでは、nake
の後ろに-ios
や-droid
、-js
などと指定することでビルドができます。
何も指定しなかった場合、現在実行中のプラットフォーム向けのビルドが行われます。
詳しくは公式を参照してください。
ちなみに、Android向けのビルドにはAndroid NDKが必要なようです。
最後に
Nim本体でmasterで実装されていないプロシージャを参照しているという僕としては初めてのタイプのエラーに遭遇し、バージョンが1未満の言語を実感しました(?)
普段はAndroidを触っているということもあり本当はモバイル向けにUIを色々弄ってみたかったのですが入門記事みたくなってしまいました。*4 これはこれで誰かの導入の一助になれればと思います。
*1:詳細はnimbleのドキュメントを参照
*2:https://github.com/yglukhov/nimx/blob/master/doc/layout-dsl.mdより
*3:僕はdevelブランチを見ました
*4:絶対加筆or別記事でやるぞ2018冬