99
3-2 RAD Studio で Hello world を作る
1
2
3
4
5
6
7
3-2 RAD Studioで Hello worldを作る3-2 RAD Studioで Hello worldを作る さて、ではいよいよ RAD Studioを触っていきます。RAD Studioを起動してメニューの
「ファイル」→「新規作成」から「FireMonkeyモバイルアプリケーション」を選択します(図
3.11)。
図3.11●プロジェクトの新規作成メニュー
次に、種類を選択するダイアログが開くので、空のアプリケーションを選択します(図
3.12)。
図3.12●アプリケーションの種類選択ダイアログ
3
100
初めての iOSアプリケーション
すると iPhoneの画像が表示された Formが表示されるので、第 2章でやったように、ツール
パレットから TLabelと TButtonを置いてみます(図 3.13)。
図3.13●コントロールの配置
さて、ここからボタンとイベントを関連づけます。Button1を選択した状態で、オブジェク
トインスペクタのイベントタブで OnClickをダブルクリックするか、Button1そのものをダブ
ルクリックします(図 3.14)。
101
3-2 RAD Studio で Hello world を作る
1
2
3
4
5
6
7
図3.14●イベントハンドラの指定
するとイベントハンドラが定義されるので
Label1.Text := 'Hello world !';
と書きます。これで、もう終わりです。第 2章と同じようにプロジェクトを保存して実行する
と、Hello world !アプリが起動します(図 3.15)。
3
102
初めての iOSアプリケーション
図3.15●実行結果
デフォルトイベント
コントロールのデフォルトイベントを定義できます。たとえば TButton のデフォルトイベ
ントはOnClick になっているので、ボタンそのものをダブルクリックするとOnClick イベ
ントハンドラが生成されます。
前章と合わせて、RAD Studioと Xcodeでの開発を簡単に説明してきました。「Hello world」
のような簡単なアプリではあまり差はないように思われるかもしれません。しかし、Xcodeの
ように Controlでドラッグしてコネクションを設定する、という手順よりも、RAD Studioのよ
うにオブジェクトインスペクタで必要なイベントをダブルクリックしてイベントハンドラを作
る方が直感的ではないでしょうか。また、前章で説明したように、RAD Studioは 2Way-Tools
なので IDE上での変更は即座にコードに反映され、不整合が起きないようになっています。
他にも、Xcodeにはコネクションを直感的かつ俯瞰的に見るツールがありませんが、RAD
Studioにはオブジェクトインスペクタがあり、どのコントロールのイベントがどのような名前
COLUMN
103
3-3 カップラーメンタイマーを作ろう
1
2
3
4
5
6
7
で定義されているのかを簡単に知ることができます。しかも、この開発スタイルはWindowsで
も iOSでも、近々サポートされる Androidであっても変わることがありません。あるバージョ
ンから UIが大きく変わったり、InterfaceBuilderから Storyboardを使うように変わるといった
こともほとんどありません。
そのため、Windowsプログラマでも Delphiの経験があればすんなりと iOSの開発に入れま
すし、これからプログラミングを始める方々なら、一度 Delphiに触ってしまえばさまざまなプ
ラットフォームに対応できるのです。
FireMonkey がWindows上でも実行可能であることの意味
FireMonkey で作成した iOSアプリケーションはPAServer を経由して実行するため、ア
プリケーションの配置にそこそこ時間が掛かります。毎回、この時間を待つのは苦痛かもし
れません。
しかし、FireMonkey はマルチプラットフォームに対応したフレームワークです。ターゲッ
トOSをWindowsにすれば、そのままWindowsで動作するアプリケーションになります。
そのアプリケーションは当然PAServer を経由しないため、コンパイル後すぐに実行されま
す。つまり、Windows 上で実行しながら大枠の動きを確認しつつ、要所要所で iOSシミュ
レータや iOSデバイスで実行するということが簡単にできるのです。これは開発効率の向上
に大いに寄与することでしょう。
3-3 カップラーメンタイマーを作ろう3-3 カップラーメンタイマーを作ろう さて、それではここからは Xcodeのことを忘れて、RAD Studioで色々作っていきましょう。
まずは、簡単なカップラーメンタイマーを作ります。ただ 3分経ったらアラームが鳴る、とい
うのでは生麺タイプのカップラーメンに対応できないので、何分経ったら鳴るか設定できるよ
うにしましょう。新しく FireMonkeyモバイルアプリケーションを作成します。
プロジェクト名は「CupRamenTimer.dproj」、ユニットは「uMain.pas」として保存します。
COLUMN
3
104
初めての iOSアプリケーション
ユーザーインターフェースの作成 では、Form1をクリックして、まず名前を変えます。コンポーネントの名前は、オブジェク
トインスペクタの Nameプロパティを編集すると変更できます。ここでは「frmMain」としま
す(図 3.16)。
図3.16●Nameプロパティ
次に、ツールパレットで TToolBarを検索して、フォームにドロップします(図 3.17)。
図3.17●Alignプロパティ
TToolBarをドロップすると、自動的に TToolBarが画面最上部に配置されたと思います。こ
105
3-3 カップラーメンタイマーを作ろう
1
2
3
4
5
6
7
れは、Alignプロパティの作用です。Alignプロパティに「alTop」という値を設定すると、画
面上部に配置され動かすことができなくなります。
Alignプロパティの代表的な値について、表 3.1にまとめます。
表3.1●Alignプロパティの代表的な値
値 説明alTop 親領域の上部にフィット。幅は親領域の幅と同じ大きさ。alBottom 親領域の下部にフィット。幅は親領域の幅と同じ大きさ。alLeft 親領域の左部にフィット。高さは親領域の高さと同じ大きさ。alRight 親領域の右部にフィット。高さは親領域の高さと同じ大きさ。alClient 親領域の空いている領域にフィットする大きさになる。alCenter 親領域の中央に表示される。
これらの値は画面が回転しても有効で、回転に追随し位置を自動的に変更します。
ToolBarの名前は「barTitle」とでもしておきましょう。次に TLabelを置き、構造ペインで
ToolBarの子にします。名前は「lblTitle」とし、Textプロパティに「カップラーメンタイマー」
と入れます(図 3.18)。
図3.18●Textプロパティ
3
106
初めての iOSアプリケーション
しかし、ラベルの内容の表示が少し変です。これは、ラベルの幅が足りないため、ラベルの
内部で文字列が改行されてしまったためです。グリップを掴んで幅を広げても構わないのです
が、ここでは AutoSizeプロパティを使いましょう。AutoSizeプロパティにチェックを入れて
Trueにします。この変更は即座に反映され、ラベルの中身の文字列に合わせて自動的にラベル
の幅と高さが変わります(図 3.19)。ラベルを使う際、AutoSizeは非常に便利なので覚えてお
くと良いプロパティの 1つです。
図3.19●AutoSizeプロパティ
さて、ラベルの文字は表示されるようになりましたが、まだ iOSらしくはありません。iOS
で ToolBarに表示される文字列と同じように表示させるためには、StyleLookupプロパティを
使います。StyleLookupプロパティをクリックするとコンボボックスが開き、このコンポーネ
ントに適用できるスタイルの一覧が表示されます(図 3.20)。
107
3-3 カップラーメンタイマーを作ろう
1
2
3
4
5
6
7
図3.20●StyleLookupプロパティ
ToolBarに表示するラベルなので、StyleLookupは「toollabel」を選びます。すると自動的に
フォントカラーなどが変わって ToolBarらしい表示になりました(図 3.21)。
図3.21●Style適用後
3
108
初めての iOSアプリケーション
それから、ラベルの位置も中途半端なので調整しておきましょう。Alignプロパティを
「alClient」にします。AutoSizeプロパティは Trueのままでも問題がありませんが、必要なくな
るので Falseにします(図 3.22)。
図3.22●Alignの設定
ラベル内に表示するテキストの位置は TextAlignプロパティで設定します。TextAlignプロパ
ティに設定する値を表 3.2に示します。
表3.2●TextAlignの値
値 説明taCenter 中央寄せtaLeading 左寄せtaTrailing 右寄せ
ここではテキストを中央寄せにするために「taCenter」にします(図 3.23)。
109
3-3 カップラーメンタイマーを作ろう
1
2
3
4
5
6
7
図3.23●TextAlignプロパティ
これでタイトル部分はそれっぽくなりました。
次に、アラームが鳴るまでの時間を指定するコントロールと、その時間を分単位で指定する
ことを示すラベルを 2つ置きます。ここでは、時間を指定するコントロールには TSpinBoxを
使いましょう。名前は、それぞれ「spinTimer」、「lblTimerPrefix」、「lblTimerSuffix」としました。
また、ラベルは AutoSizeプロパティを Trueにしてあります(図 3.24)。lblTimerPrefixの Text
プロパティには「じゃぁ、いつ鳴らすの?」を、lblTimerSuffixの Textプロパティには「分後
でしょ」の文字列をそれぞれ設定します。
3
110
初めての iOSアプリケーション
図3.24●SpinBoxとプロパティ
この 3つのコンポーネントは、まとめて中央寄せにしてみましょう。[Ctrl]キーを押しなが
らドラッグすることで複数のコンポーネントを一度に選択できるので、そうして選択したコン
ポーネント群を右クリックして「位置揃え」を選択します(図 3.25)。
図3.25●複数のコンポーネントを選択し、位置揃えを行う
111
3-3 カップラーメンタイマーを作ろう
1
2
3
4
5
6
7
すると、「位置揃え」ダイアログが現れるので、「水平位置揃え」を「ウィンドウの中央に置く」
にします(図 3.26)。
図3.26●位置揃えダイアログ
これで中央に揃いました(図 3.27)。
図3.27●選択したコントロールが中央に揃う
さらに、ラベルを 2つとボタンを 1つ追加し、次のように設定します。
(1) ラベル
名前 lblRestTimePrefix
Textプロパティ 残り
3
112
初めての iOSアプリケーション
(2) ラベル
名前 lblRestTime
Textプロパティ 00:00
Font.Sizeプロパティ 64
Font.Styleプロパティ fsBold
(3) ボタン
名前 btnStart
Textプロパティ 開始
(1)のラベルは、(2)のラベルの内容の説明に使います。(2)のラベルには、タイマーが開
始してからの残り時間を秒単位で表示します。文字が目立つように、大きなサイズで太字で表
示するようにしています(図 3.28)。また、先ほどの位置揃えダイアログを使ってウィンドウ
の中央に配置しましょう。(3)のボタンはタイマーをスタートさせるために使います。
図3.28●Fontプロパティ
今度は、非ビジュアルコンポーネントを 2つ貼ります。TTimerと TMediaPlayerです。
TTimerは Intervalプロパティで設定した時間(ミリ秒)が経過したときに OnTimerイベントを
発生させます。この機能を使って指定した分数の後にイベントが来るようにしましょう。
113
3-3 カップラーメンタイマーを作ろう
1
2
3
4
5
6
7
Timerの名前は「timerRestTime」としました。今回のアプリケーションの有効数字は 1秒で
すが、少し精度を上げるために Intervalプロパティには「500」を設定します。ここで重要なの
がEnabledプロパティです。TimerのイベントはEnabledプロパティがTrueの場合に発生します。
ここでは、開始ボタンを押してから Timerイベントが発生して欲しいので、Enabledプロパ
ティは Falseにしておきます。
TMediaPlayerは指定した音声ファイルを再生するコンポーネントです。FileNameプロパ
ティにMP3ファイルを指定して、Playメソッドを呼ぶだけです。2つ貼った状態が図 3.29
です。
図3.29●TTimerとTMediaPlayer
次に、実際に鳴らすMP3を配布パッケージ(IPA)に含めます。そこで使うのが「配置マネ
ージャ」です。配置マネージャは、メニューの「プロジェクト」→「配置」で起動します(図
3.30)。
3
114
初めての iOSアプリケーション
図3.30●配置マネージャを開くメニュー
配置マネージャの「ファイルの追加」ボタンから、鳴らすMP3ファイルを選択します(図
3.31、図 3.32)。
図3.31●配置マネージャ
115
3-3 カップラーメンタイマーを作ろう
1
2
3
4
5
6
7
図3.32●MP3を選ぶダイアログ
追加されると図 3.33のようになります。
図3.33●MP3が追加される
ここでリモートパス欄をクリックして、リモートパスを「.¥StartUp¥Documents」に修正しま
す(図 3.34)。
3
116
初めての iOSアプリケーション
図3.34●パスの修正
こうすると、Documents/alarm.mp3として参照できるようになります。このように簡単にリ
ソースを含めることができます。
さて、ここまでで GUIができました。構成ペインは次のようになっていると思います。
frmMain barTitle(TToolBar) lblTitle(TLabel) btnStart(TButton) lblRestTime(TLabel) lblRestTimePrefix(TLabel) lblTimerPrefix(TLabel) lblTimerSuffix(TLabel) spinTimer(TSpinBox) playerAlarm(TMediaPlayer) timeRestTime(TTimer)
※構成ツリーのコンポーネントの名前の後ろの括弧内はコンポーネントのクラス名
コーディング では、次にコーディングに入ります。作成するイベントハンドラは、btnStartの OnClick、
timerRestTimeの OnTimer、frmMainの OnCreateの 3つです。すでに説明しましたが、イベン
117
3-3 カップラーメンタイマーを作ろう
1
2
3
4
5
6
7
トハンドラはダブルクリックで作成できます。
ソースコードを次に示します。
リスト3.3●カップラーメンタイマーのソースコード
unit uMain;
interface
uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.StdCtrls, FMX.Edit, FMX.Media;
type TfrmMain = class(TForm) barTitle: TToolBar; lblTitle: TLabel; spinTimer: TSpinBox; lblTimerPrefix: TLabel; lblTimerSuffix: TLabel; lblRestTime: TLabel; btnStart: TButton; lblRestTimePrefix: TLabel; timerRestTime: TTimer; playerAlarm: TMediaPlayer; procedure btnStartClick(Sender: TObject); procedure timerRestTimeTimer(Sender: TObject); procedure FormCreate(Sender: TObject); private { private 宣言 } // 変数宣言 ----------------------------------------------------------------------------------------------------------------------------------------① FTime: TDateTime; FTargetTime: Integer; FStarting: Boolean; // メソッド ----------------------------------------------------------------------------------------------------------------------------------------② procedure SetAllEnabled(const iEnabled: Boolean); procedure SetTime(const iRestTime: Integer); public { public 宣言 } end;
3
118
初めての iOSアプリケーション
var frmMain: TfrmMain;
implementation
uses System.DateUtils; // ユニットの使用を宣言 -------------------------------------------------------------------------------------③
{$R *.fmx}
// btnStart の OnClick イベントハンドラ --------------------------------------------------------------------------------------------④procedure TfrmMain.btnStartClick(Sender: TObject);begin if (FStarting) then begin SetAllEnabled(False); end else begin if (spinTimer.Value = 0) then ShowMessage('何分後にアラームを鳴らすか選択してください') else begin FTime := Now; FTargetTime := Trunc(spinTimer.Value) * 60; SetAllEnabled(True); SetTime(FTargetTime); end; end;end;
// frmMain の OnCreate イベントハンドラ --------------------------------------------------------------------------------------------⑤procedure TfrmMain.FormCreate(Sender: TObject);begin playerAlarm.FileName := GetHomePath + PathDelim + 'Documents' + PathDelim + 'alarm.mp3';end;
// Enabled の切り替え -----------------------------------------------------------------------------------------------------------------------------⑥procedure TfrmMain.SetAllEnabled(const iEnabled: Boolean);begin FStarting := iEnabled; timerRestTime.Enabled := iEnabled; spinTimer.Enabled := not iEnabled;
119
3-3 カップラーメンタイマーを作ろう
1
2
3
4
5
6
7
if (iEnabled) then begin btnStart.Text := '停止'; SetTime(FTargetTime); end else begin btnStart.Text := '開始'; SetTime(0); end;end;
// lblRestTime に残り時間を表示 -----------------------------------------------------------------------------------------------------------⑦procedure TfrmMain.SetTime(const iRestTime: Integer);begin lblRestTime.Text := Format('%.2d:%.2d', [iRestTime div 60, iRestTime mod 60]);end;
// timerRestTime の OnTimer イベントハンドラ ----------------------------------------------------------------------------------⑧procedure TfrmMain.timerRestTimeTimer(Sender: TObject);var Diff: Integer;begin Diff := SecondsBetween(Now, FTime);
if (Diff > FTargetTime) then begin SetAllEnabled(False); playerAlarm.Play; ShowMessage('今でしょ!'); end else SetTime(FTargetTime - Diff);end;
end.