2013-12-03

GtkAdventCalendarで作るアドベントカレンダーアプリ

GNOME Advent Calendar 2013 の3日目の記事です。 2日目はクリアコードさんのGTK-Docの使い方 でした。

今回は、 1日目 に作成した GtkAdventCalendar をライブラリーとして使い、
カスタマイズしたアドベントカレンダーアプリを作成します。
(今回は、前回に増してRubyの話がほとんどで、GNOMEっぽくないです)

まずは、GtkAdventCalendarをライブラリーとして使いやすいように修正します。

修正点

  1. 日付ボタンをクリックしたときの動作を変更しやすくする
    • メソッドに切り出す
  2. requireで読み込みやすくする

具体的には以下の通りです。

1. 日付ボタンをクリックしたときの動作を変更しやすくする

lib/gtk_advent_calendar/calendar.rb

修正前

module GtkAdventCalendar
  class Calendar
    ...
    def day(n)
      ...
      button.signal_connect("clicked") do
        show_uri("http://en.wikipedia.org/wiki/December_#{n}")
      end
      ...
    end
    ...
  end
end

修正後

module GtkAdventCalendar
  class Calendar
    ...
    def day(n)
      ...
      button.signal_connect("clicked") do
        action(n)
      end
      ...
    end

    def action(n)
      show_uri("http://en.wikipedia.org/wiki/December_#{n}")
    end
    ...
  end
end

これで、action(n)メソッドを上書きするだけで、日付のボタンを
押したときの動作を変更することができるようになりました。

2. requireで読み込みやすくする

Rubyでは、ライブラリーは主にrequireコマンドで読み込みますが、
ファイル名まで指定するのは面倒です。(前回の Commandクラス を参照)

そこで、ライブラリー名だけでCalendarクラスを読み込めるようにします。

lib/gtk_advent_calendar.rb

修正前

require "gtk_advent_calendar/version"

ここにパスを書いておくと、require "gtk_advent_calendar"で読み込まれます。

versionを読み込んでいる行は、bundle gemコマンドでRubyGems用の
雛形を作成したときに生成されたものです。そこにcalendarも追加します。

修正後

require "gtk_advent_calendar/version"
require "gtk_advent_calendar/calendar"

これで、require "gtk_advent_calendar"と書くだけで
GtkAdventCalendar::Calendarクラスが使えるようになりました。

参考までに、RubyGemsの雛形については @hibariya さんのスライドに
わかりやすくまとまっています。興味のある方はぜひご覧ください。
https://speakerdeck.com/hibariya/code

インストール

ライブラリーとして使う場合も、前回と同様にgemコマンドでインストールします。

% gem install gtk_advent_calendar

README に記載されている通り、Gemfile等に記述してもOKです。

サンプルコード

以下のように使います。

sample/your_calendar.rb

#!/usr/bin/env ruby

require "gtk_advent_calendar"

class YourCalendar < GtkAdventCalendar::Calendar
  # @params n [Integer] the day between 1 and 25.
  def action(n)
    puts "It's December #{n}."
  end
end

window = Gtk::Window.new
window.add(YourCalendar.new)
window.signal_connect("destroy") do
  Gtk.main_quit
end
window.show_all
Gtk.main

元々はWebページが開かれていましたが、標準出力に日付を表示するようにしています。
show_uriメソッドは使えるので、別のWebページを開くようにすることもできます。

  def action(n)
    show_uri("http://hoge.fuga/piyo/#{n}")
  end

まとめ

GtkAdventCalendar gem使って、カスタマイズしたアドベントカレンダーアプリを作成しました。

アプリケーションを作成したら、ライブラリーとしても使いやすくすると
使われる機会が増えるかもしれません。(WebページとAPIの関係に似ていますね)
(ライブラリー部分を別のgemに切り出す方が普通かもしれません)