2013-12-01

Ruby/GTK3で作るカレンダーアプリ

GNOME Advent Calendar 2013 1日目の記事です。

Ruby/GTK3を使って、Advent Calendarっぽいアプリを作成します。

機能

  • GUIウィンドウを持つ
  • 1日〜25日までのボタンを付ける
  • 日付のボタンをクリックすると、何かが開く
    • とりあえずWebページ(Wikipedia)にしておく

インストール

RubyGems.orgに公開したので、以下のコマンドでインストールできます。

% gem install gtk_advent_calendar

もしインストールできなかったら、 issuesTwitter でメンションをいただけるとうれしいです。

起動

コマンドラインから起動できます。

% gtk_advent_calendar

ソースコード

ソースコードはGitHubに公開してあります。
https://github.com/myokoym/gtk_advent_calendar

簡単に解説します。

実行ファイル

コマンドラインから実行するためのファイルです。

https://github.com/myokoym/gtk_advent_calendar/blob/master/bin/gtk_advent_calendar

#!/usr/bin/env ruby

require "gtk_advent_calendar/command"

GtkAdventCalendar::Command.run

実行ファイルなので、shebangを付けています。
あとは、Commandクラスのrunメソッドを呼び出しているだけです。

GUIウィンドウ・メインループ

CommandクラスでGUIウィンドウを作成しています。

https://github.com/myokoym/gtk_advent_calendar/blob/master/lib/gtk_advent_calendar/command.rb

require "gtk3"
require "gtk_advent_calendar/calendar"

module GtkAdventCalendar
  class Command
    class << self
      def run
        window = Gtk::Window.new
        window.title = "Advent Calendar"
        window.add(Calendar.new)
        window.signal_connect("destroy") do
          Gtk.main_quit
        end
        window.show_all
        Gtk.main
      end
    end
  end
end

主役はwindow.add(Calendar.new)のCalendarクラスです。
Gtk.mainでGUIアプリケーションのメインループに入ります。

Calendarクラス

ここでカレンダー本体を作ります。

GTKにはいろいろなウィジェットがありますが、
ここでは基本的なウィジェットであるBoxを多用します。

https://github.com/myokoym/gtk_advent_calendar/blob/master/lib/gtk_advent_calendar/calendar.rb

require "gtk3"

module GtkAdventCalendar
  class Calendar < Gtk::Frame
    LAST_DAY = 25
    CELL_WIDTH = 40

    def initialize
      super
      @day = 1
      add(month)
    end

    def month
      box = Gtk::Box.new(:vertical)
      box.add(days_of_the_week)
      while @day <= LAST_DAY do
        box.add(week)
      end
      box
    end

    def days_of_the_week
      box = Gtk::Box.new(:horizontal)
      %w(Sun Mon Tue Wed Thu Fri Sat).each do |day_of_the_week|
        label = Gtk::Label.new("#{day_of_the_week}.")
        label.width_request = CELL_WIDTH
        box.add(label)
      end
      box
    end

    def week
      box = Gtk::Box.new(:horizontal)
      7.times do
        break if @day > LAST_DAY
        box.add(day(@day))
        @day += 1
      end
      box
    end

    def day(n)
      button = Gtk::Button.new(:label => n.to_s)
      button.width_request = CELL_WIDTH
      button.height_request = CELL_WIDTH
      button.signal_connect("clicked") do
        show_uri("http://en.wikipedia.org/wiki/December_#{n}")
      end
      button
    end

    def show_uri(uri)
      case RUBY_PLATFORM
      when /darwin/
        system("open", uri)
      when /mswin|mingw|cygwin|bccwin/
        system("start", uri)
      else
        if Gtk.respond_to?(:show_uri)
          Gtk.show_uri(uri)
        else
          system("firefox", uri)
        end
      end
    end
  end
end

詳しい解説は省略するので、何かあればコメントか Twitter でメンションをください。

まとめ

Ruby/GTK3を使ってカレンダーアプリを作成しました。
これを応用すれば、ランチャーアプリなども簡単に作れると思います。

もしRuby/GTK3に興味を持たれた方がいれば、
プロジェクトページメーリングリスト も参照してみてください。

2日目はクリアコードさんの GTK-Docの使い方 です!