tokuhirom's Blog

ちょっとした GUI アプリケーションをつくるのに MacRuby はよい選択肢となりうる

ちょっとした GUI アプリをつくるのに MacRuby をつかってみた。結論からいうと MacRuby はよくできているなあ、という印象をえた。

昔、RubyCocoa をさわってみたことはあったのだけど RubyCocoa は

「なんか正直 Objective-C の方がむしろ楽な気がする。。」

という感じだった。なにしろめんどくさいという印象しかのこらなかったのである。

一方、 MacRuby はいいな。 Syntax をカスタマイズすることにより無理矢理実現している変態的な感じもよい。実用的。

ちょっとした自分用ツールをかくときに今までは web application としてかいていたのだけど、MacRuby の方が楽だな、そんな気分になったのであった。
(というか、最初 Web Application としてかいてつかっていたツールを MacRuby に移植したのである)
VB でアプリかくとき並の楽さだ(XCode がバージョンごとに UI がかわっておいつくのがダルいという点をのぞけば、だけど)。

ツール自体は非常にシンプルなもので、以下のようなコードです。仕事上、毎日確実にやっておかないといけないことのチェックリストを実現するというアプリ(自分専用ツールなので、タスクリストがハードコードだったりします)。

#
#  AppDelegate.rb
#

class Task
    attr_accessor :title
    attr_reader   :done_time

    def initialize(title)
        @title = title
        @done_time = nil
    end

    def done?
        return @done_time && @done_time.strftime("%Y-%m-%d") == Time.now.strftime("%Y-%m-%d")
    end

    def done!
        @done_time = Time.now
    end

    def toggle!
        if self.done?
            @done_time = nil
        else
            self.done!
        end
    end

    def refresh!
        if @done_time && @done_time.strftime("%Y-%m-%d") != Time.now.strftime("%Y-%m-%d")
            @done_time = nil
        end
    end
end


class AppDelegate
    attr_accessor :window
    attr_accessor :table_view

    @@tasks = [
        'gmail check',
        '○○ mail check',
        'redmine check',
        'google calendar check',
        '○○ calendar check',
        '○○ check(night)',
    ].map {|x|
        Task.new(x)
    }

    def applicationDidFinishLaunching(a_notification)
        # Insert code here to initialize your application
        @refresh_thread = Thread.start do
            while 1
                self.refreshTasks()
                @table_view.reloadData
                sleep 10
            end
        end
    end

    def numberOfRowsInTableView(aTableView)
        @@tasks.size
    end
    
    def tableView(aTableView, objectValueForTableColumn: aTableColumn, row: rowIndex)
        case aTableColumn.identifier
        when 'task'
            aTableColumn.dataCell.title = @@tasks[rowIndex].title
            @@tasks[rowIndex].done?
        when 'time'
            task = @@tasks[rowIndex]
            if task.done?
                task.done_time.strftime("%H:%M")
            else
                ''
            end
        else
            throw "Should not reach here"
        end
    end

    # - (void)tableView:(NSTableView *)tableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
    def tableView(aTableView, setObjectValue: anObject, forTableColumn: tableColumn, row: row)
        @@tasks[row].toggle!
        @table_view.reloadData
    end

    def refreshTasks
        @@tasks.each do |task|
            task.refresh!
        end
    end
end

で、MacRuby の入門にはこちらのサイトがよくまとまっていた。
http://watson1978.github.com/MacRuby-DoJo/

あと MacRuby.h がないといわれるむきにはこのページを参照。
http://blog.i462soft.com/2012/06/xcode-4.html