2008-03-18
目次
りんご味Ruby 第21回 藤本 尚邦
第17回から第19回にかけて、Objective-Cで書かれているXcode ToolsのサンプルアプリケーションSketchに、RubyCocoaフレームワークをリンクして、Rubyプログラムで機能(新たな種類のグラフィックオブジェクトなど)を追加していく様子を示してきました:
・Sketchプロジェクトに、Rubyプログラムを組み込むための準備 (第17回)
・角丸四角形を表すSKTRoundedRectangleクラスをRubyで実装 (第18回)
・ツールパレットに角丸四角形ツールを追加 (第19回)
■ 角丸四角形対応Sketchアプリのビルド・実行
第19回では、InterfaceBuilderを使って角丸四角形ツールボタンを追加し、ツールパレットコントローラ(SKTToolPaletteController.m) に角丸四角形のためのコードを追加しました。実はこれで、Sketchアプリケーションで角丸四角形を描くために必要なものは基本的に出来上がっています。
ということで、Sketchプロジェクトをビルドして、改造したSketchアプリケーションを走らせてみましょう。ツールパレットで角丸四角形ツールを選択してウィンドウ内に図形を作ると、角丸四角形が作成できるようになっています。Objectve-Cで定義された四角形クラスや楕円クラスと、Rubyで実装された角丸四角形クラスを同等に扱うことができているわけです。
■ スクリプティングブリッジ
Sketchアプリケーションはスクリプティングに対応していて、AppleScriptなどでグラフィックを生成したり属性を変更したりすることができるようになっています。以下は、Sketchアプリケーションのドキュメント上に、四角形オブジェクトを1つ生成して、位置やサイズをセットするAppleScriptのプログラムです:
tell application "Sketch"
tell document 1
make new box
tell box 1
set width to 100
set height to 100
set x position to 100
set y position to 100
set stroke thickness to 8
end tell
end tell
end tell
LeopardからMac OS Xに搭載されるようになったScriptingBridgeフレームワークを使うと、Objective-CやRubyのプログラムからも同様のアプリケーション操作が可能になります。以下は、上のAppleScriptプログラムと同様の操作を(RubyCocoaフレームワークを使って)Rubyでプログラムしたものです:
--------------- ScriptingBridgeを使ってSketchアプリケーションを操作 --
require 'osx/cocoa'
include OSX
require_framework "ScriptingBridge"
# Sketchアプリケーションオブジェクトを取得してsketchという名前を付けた
sketch = SBApplication.
applicationWithBundleIdentifier("com.apple.CocoaExamples.Sketch")
# スクリプティングの用語集で"box"という名前が付けられている四角形グラ
# フィッククラス(SKTRectangleのこと)にbox_classという名前を付けた
box_class = sketch.classForScriptingClass("box")
# 四角形オブジェクトを生成
box = box_class.alloc.init
# ドキュメントに生成した四角形オブジェクトを追加
sketch.documents[0].graphics.addObject(box)
# 追加した四角形オブジェクトに各種属性値を設定
box.width = box.height = 100
box.xPosition = box.yPosition = 100
box.strokeThickness = 8
-------------------------------------------
ちなみに前回紹介したMacRubyを使って書く場合には、最初の3行の部分を:
framework “ScriptingBridge”
に置き換えるだけで、あとは同じになるはずです。
さて、角丸四角形グラフィックをスクリプティングに対応させるためには、以下の3つのファイル:
・SKTDocument.m
・Sketch.scriptSuite
・Sketch.scriptTerminology
を変更する必要がありそうです。次回はこれに着手しようかとも考えていたのですが、Rubyとほとんど関係のない話になってしまいそうな気もします。もっとRubyよりの別の話に予定変更するかもしれません。
藤本裕之のプログラミング夜話 #134
承前、前回は各種(というほど多くないか)統計調査をひき、「パソコンが普及したわりにソフトウェアがそれに比例して売れてない」理由は、「ほとんどの人が買ったそのままで出来ることしかパソコンをつかってやってないから」であることを確認したわけだが覚えてますか? いや別にあなたが覚えてなくてもそのまま話は進むんだけどさ。
前回みた日米韓のパソコンの用途調査で(と書くとまるでオレが調査したみたいで偉そうだが)、米韓のトップは「音楽を聴く」であった。日本人だって結構パソコンで音楽を聴いているような気がするんだけど、とある人にいったら「フジモトさん、日本人が音楽を聴いているのはケータイでなんですよ」という返事が返ってきた。
そんなぁ、音楽のオンライン配信において iTunes Storeのシェアが6割だとか聞いたことがありますよと聞き返したら、なんとそれは「ケータイへの音楽配信を入れない、パソコン相手だけの数字」なんだそうな。そんで、iTunesStoreが6割を占める パソコン相手の音楽配信の市場規模というのはケータイ相手を含むこの業種全体の中ではなんと1割程度なんだと。がーん、と思いましたか(正直オレは思いました)?
なんつうかさぁ、井の中の蛙大海を知らずというか、蛙の胃の中の寄生虫が井戸も知らないような話である(いくらなんでもそこまでひどかないか)。そうなのだ、なんと情報機器としてのパソコンは、その主流の地位をケータイに明け渡したどころか(いくら世間知らずのオレでもそのくらいは知ってたけどさ)、知らないうちに10倍とかいう差をつけられちゃっていたのである。
もちろんマクロな視点で見れば、パソコンで動いてるのもiPodで動いているのもケータイで動いているものアプリケーションには違いなく、それを書いてるのもプログラマーに違いないわけで、最初に高橋編集長からいただいた「アプリケーション・プログラマは絶滅危惧種か?」というテーマに沿えば「いいえ違います。彼らは絶滅したんではなく住処を変えて生き延びたのです」と言える。言えることはね。
だけどそれはまるで「クジラはどうして海に住むようになったのですか」みたいな話である。何代か先の子孫は知らず(いないけど)、陸の動物としてこれまでやってきた人々がおいそれとクジラやイルカになれるか。いや、なれれば言うことはないんだがコトはそう簡単ではない。それにそのケータイという「海」だってそれほど生活環境として結構なところではあるまい。隣の芝生はいつでも青い。もしかしたら中国の緑化運動みたいに緑のペンキを撒いてるだけかも知れない。
私としてはここらでもう一度原点に戻り、そもそも俺たちが飯の種にしているアプリケーション……つうかソフトウエアつうのは何であるのか。いわゆる「それがないとコンピュータがただの箱であるところのもの」とかいう古いプログラム入門の最初の方に書いてあるようなことでなく、人がそれを作ることを生業として生活して行く商品、あるいは製品としてこいつがどんな性格のものであるのかというところを考えてみたい。
……て、いうかね。実を言うとオレはもうかなり長い間、そう、かれこれ10年以上も前から、俺たちが作っているこいつは実のところ「ソフトウエアの名に値しない何か」なんぢゃないかと思っているのである。……これぢゃ通じないかな、こういう風に考えてみてください。「コンピュータ・ソフトウエアというものはもっと広いカテゴリである『ソフトウエア』の中でどんな存在なんだろう」って。
(以下次回 2008_03_15)
高橋真人の「プログラミング指南」第132回
〜XcodeによるPowerPlant X入門(21)〜
こんにちは、高橋真人です。
さて、前回お勧めしたようにイベントハンドラの中にログを書き出すコードを加えて、MyViewの挙動を観察してみましたでしょうか?
今回4つのクラスを継承することで加えられたCarbonイベントのハンドラとして機能するメンバ関数は以下の通りです。(カッコ内は継承元のクラス)
DoControlDraw()【PPx::ControlDrawDoer】
DoControlHit()【PPx::ControlHitDoer】
DoControlHitTest()【PPx::ControlHitTestDoer】
DoControlHiliteChanged()【PPx::ControlHiliteChangedDoer】
それでは、通常のプログラムの動作に沿って、それぞれのハンドラ(関数)がどのように呼ばれるかを見ていきましょう。
まず、最初に呼ばれるのはDoControlDraw()です。このハンドラはユーザーにViewの見た目を提供する重要な役目を持っており、Viewの表示が必要になった時に呼ばれます。
そのため、この関数の実装には「状態の判断」の処理が入ります。今回のプログラムでは「Viewがアクティブであるか」と「Viewがハイライトされているか」をチェックし、この両方を満たす場合には表示色が濃くなるようにしています。
さて、ユーザーがマウスでこのViewを押したとします(ボタンはまだ放さない)。すると、DoControlHitTest()が呼ばれます。この関数の処理の中心は、「Viewのどの部分が押されているのか」を判断することです。少し分析的に言い替えると「マウスポインタの現在の位置は、Viewのどの部分か」ということです。
「部分」というのは何のことかということですが、例えばスクロールバーのような複雑なコントロールを思い浮かべてもらうと分かると思うのですが、コントロールにはいろいろな構成パーツが存在していて、それぞれ独自の反応をするということです。今回は極めて単純な四角のボタンですから、構成部品は“ボタン”のみということで、コードで表すとkControlButtonPartとなります。
ちなみに、これらの「コントロールの構成部分名」を表す値は
ControlDefinitions.hというヘッダファイルに定義されています。Xcodeで、コードのkControlButtonPartという部分をコマンドキーを押したままでダブルクリックするとこのヘッダファイルが開き、kControlButtonPartの定義部分が選択された状態になると思います。選択部分の少し上には、”Control PartCodes”と、コメントで見出しが付けられていて、以下、enum型として“部品名”が羅列されているのをご覧になれると思います。
さて、今回のプログラムでViewが表現しているのは、あくまでシンプルな四角形のボタンですから、構成部分はkControlButtonPart以外にありません。もしかしたら、「構成部品が一つしかないのだし、ハンドラが呼ばれるのはボタンが押された時に決まっているのだから、位置判定など必要ないのでは?」と思われる方もいるかもしれません。この点については、すぐ後で判明します。
さて、このハンドラでマウスポインタがViewの中にあると判断されたら、outPartCodeにkControlButtonPartをセットしてやるわけですが、これによって新たなイベントが引き起こされます。それに伴って呼び出されるハンドラがDoControlHiliteChangedです。
このイベントはViewのハイライト状態が変化した場合に発生します。ハイライトというのは、通常のMacのコントロールにおいてマウスクリックに反応して色が青くなったり濃くなったりするような状態のことです。
まず、Viewの上でマウスボタンを押したら、ボタンを押さえたままでポインタをボタンの外に出したり、戻したりと、あちこち動かしてみてください。もし、DoControlHitTest()の中に、冒頭でも触れたログを書き出すコードを書いてあった場合、マウスボタンを押したままでポインタの位置が変化すると、頻繁にこの関数が呼び出されることが観察できるはずです。
このとき内部では、outPartCodeに返ってくる値を見張っていて、これが変化した時にその内容に沿った処理をします。今回のプログラムでは変化はkControlButtonPartとkControlNoPart(Controlのどの部分でもないことを表す)の2つの状態を行き来するだけですが、その度にHiliteControl()を呼び出して「ボタンのハイライト状態」をオンにしたりオフにしたりしているのです。
この「オンとオフの切り替え」は、ボタンのハイライト状態の変化として認識されて、また新たなイベントの発生につながります。この時、イベントのハンドラであるDoControlHiliteChanged()が呼び出されるわけです。この関数の中では、単にViewに再描画命令を発生させているだけですが、これによりView描画のイベントが発生して、DoControlDraw()が呼び出されるというわけです。
ハンドラの関数ごとに細かく説明をしたので、話が入り組んでいるように思えた方もいるかもしれませんが、DoControlDraw()、DoControlHitTest()、DoControlHiliteChanged()がどのように連携し合いながらボタンのインタラクションを実現しているかを観察してみると、そんなに難しくはないのが分かるでしょう。
重要なポイントは、これらの関数が直接に呼び出しをしているのではなく、必ずイベントを介して連携しているということです。まあ、イベントのハンドラなので当然ですが。
さて、ほとんど付け足し程度の簡単な説明になりますが、ボタン本来の目的である“クリックに対する反応”が、DoControlHit()です。この関数を呼びだすイベントは、今まで話してきたボタンのインタラクション処理の結果、「ボタンがクリックされた」と認識された場合に発生することになります。
PPx::BaseViewにイベントハンドラを加えてボタンの振る舞いをさせる仕組みが分かっていただけたでしょうか?
開発ツールよもやま話 ドキュメントアクセス 高橋 政明
待望のiPhone SDKが登場しました。NDAのため情報は公式サイトのものだけですが、既にたくさんのドキュメントがあります。
Xcodeはドキュメントへのアクセスがいくつか用意されています。今回はこれを解説します(基本部分なのでiPhone SDKでも共通なはずです)。Xcode3ガイドの第9章に「製品ドキュメントにアクセスする」があります。Xcode3ではこれまでの『「製品ドキュメント」ウインドウ』に加えて『リサーチアシスタント』も利用可能になりました。
かつて、ドキュメントは書籍の「インサイドMacintosh」や印刷物のテクニカルノートでした。APIなどを検索する専用ツールやオンラインでドキュメントを参照するツールが使われた時代を経て、現在ドキュメントは基本的にhtmlファイルで提供されブラウザで参照します。
htmlファイルは検索が可能ですし関連情報へのリンクにより、たとえばメソッドの引数の型の確認など必要な情報をたどる場合に便利です。
htmlと同じ内容のPDFのドキュメントも用意されています。pdfのドキュメントは新しいクラスを腰を据えて勉強する場合などには印刷してじっくり読む場合などに重宝します。
どのバージョンのXcodeもhtmlドキュメントを検索し対応する項目の説明を表示する機能を持っています。Xcode3の日本語表記では「製品ドキュメント」ウインドウがそれです。
◆製品ドキュメント
製品ドキュメントウインドウはヘルプメニューから開くことができます。(Xcode2.4では「マニュアル」と表記されています)
ソースリストのクラスやメソッド名をoptionキーを押しながらダブルクリックすると対応する説明を検索し結果が表示されます。サンプルや既存のソースを調べる場合など最も頻繁に検索する方法と思います。ちなみにコマンドキーを押しながらダブルクリックすると定義しているソースをEditウインドウに表示できます。
検索は検索欄に直接文字列を入力しても可能です。APIオプションで検索範囲を指定できます。APIと全文検索が選べます。(Xcode3からは「タイトル」も選べます)
全文検索ではワイルドカード「*」やブール演算子「括弧と ! & |」も使えます。例えば「path」で全文検索すると図形とファイル関係が両方ヒットしますが「path & ! file」とするとファイル関連以外を検索できます。
私がよく使うのはAPI検索です。ガイドなどにリンクがある場合はブラウザを使って開くことが多いです。
うまく表示されない場合は検索条件、特にどこから検索しているかを確認してください。「すべての製品ドキュメント」から検索しているのか「CoreReference Library」なのか「Developer Tools Reference Library」から検索するのかで検索結果は変わります。
Xcode3ではドキュメントのブラウズが可能になりました。ツールバーのブラウズボタンをクリックします。普段使っている方法で必要な情報が見つからないや広範囲に調べる場合などにこのブラウズ機能を試すとよいかもしれません。もう一度ブラウズボタンをクリックすると通常の検索に戻ります。
なおXcodeが表示するドキュメントのパスはXcode2.xでは
/Developer/ADC Reference Library
Xcode3では /Developer/Documentation/DocSets/ です。
ここにhtml形式のファイルがありインターネットに接続していない状態でもドキュメントの検索と表示が可能です。高速な検索が可能な反面鮮度は落ちて行きますので、最新ドキュメントかどうかを意識しましょう。最新ドキュメントのインストール方法はXcodeのバージョンで違いますのでヘルプを参照してください。新機能だけではなく記述が詳しくなるなど最新ドキュメントは充実する方向です。
◆リサーチアシスタント
リサーチアシスタントは情報表示に特化したパネルです。
上から順に
・外部へのリンク(別ウインドウを開く)
・宣言
・抽象
・利用できるかどうか
・関連API
・関連製品ドキュメント
・サンプルコード
必要なデータがパネルにコンパクトにまとまっています。パネルを表示した状態でキャレットのあるクラスやAPIの情報を自動的に探し、あれば表示してくれます。
Xcode3からはコンパイルオプションや警告設定の説明もリサーチアシスタントに表示されるようになっています。
◆本日のまとめ
ドキュメントを検索する方法はいろいろある。
普段使っている方法以外の検索方法も確認しておくと、いざと言う時に役に立つはずです。
◇MOSAからのお知らせと編集後記は割愛します◇