スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Lazarus特練 タイマーアプリを作ってみる

GIGAZINEを読んでいて、タイマーアプリの紹介を見つけました。

スヌーズや時間指定などの機能を搭載したカウントダウンタイマーを複数設定できる「Free Countdown Timer」 - GIGAZINE:[2012/05/23]

Lazarusを触り始めてしばらく時間もたったことだし、DelphiのTipsがかなり使えることもわかってきたので、実物をインストールせずに、妄想で再現してみる特別練習をやってみます。
アイコンは、以前に調べたことがあるので、そこから見繕ってみるとして、アラーム音が充実してそうです。
ちょっと調べてみます。

いやいや。そんなことより音なんて鳴らしたことがなかったです。
Help - Play Sound:[2012/05/23]
このへんで行けそう。

***
というわけで、GIGAZINEでもう一度よく画面をみてます。

メニューの中身は確認できないので、画面上に出てきてるボタンは、追加、編集、削除、複製、家?、ヘルプ、時計になっています。
家?は諦めて、あと時計のマークは何でしょうか?英語版にはなさそうな...
わからないので時計も諦めます。あとヘルプは必要なし。

なので、いつもの4つ、追加編集削除複製で。

***
リストの部分はというと、綺麗な感じで色ついてますが、リストボックスかな。それかグリッドかも。Delphiの思い出で話をすると、グリッドを使うと、ゼロ個の時にちょい気持ちが悪いことになるので、すっきりとリストボックスでいった方がいいでしょうか。
それか、PaintBoxにぎりぎりと自分で書くのがいいかも。

で、中身は、生き死に表示のチェックボックス、アラームまでのカウントダウン、一言、ターゲットの日時、音の名前になってます。あっと、特定の日時にするか、カウントダウンかを選べるみたいです。13:00に鳴らすか、13:00時間後に鳴らすか、ですね。

日時指定の方はいいとして、何時間後/何分後/何秒後の方は、アプリを立ち上げ直したときはどうしてるんでしょうか?というかどうが自然でしょうか。

***
我慢出来ないので、YouTubeで動作を確認してみました。
タイトルバーに現在時刻が出てます。
書式はこんなの。
>英語版: Monday, December 20, 2010 11:20:51 AM
>日本語版: 2012年5月17日 10:23:35

あと、アラーム音がなってる間=ダイアログが表示されている間は、OKを押すまでリストボックスの残時間表示部分がそのままカウントを続けています。ダイアログのOKを押すか、リストのチェックを消すかすると、ダイアログが閉じてカウントも元に戻ってる。このへんは雰囲気で。

***
チェックボックスの雰囲気良い感じです。あれは絵が見つからないと自分じゃ書けないですね。行そのものをでっかいボタン風にして凹んでたら生き、凸ってたら死ににしてみるか。

あぁもう邪魔くさくなって来ました。
どうせチラツキを抑えるために、BitBltとか書くのかと思うとメンド臭くてもう。
Lazarusじゃやったことないので、仕様を考える前にリストボックスの描画を先に終わらしてしまいます。もちろんDelphiで書いたやつを持ってくる方向で。

大切なことを忘れてました。名前です。ちなみにお手本のな前は Free Countdown Timer です。
Alarm、Timerを足してみると、足せないですね。じゃぁ、Remittで。多分TTimerは使わないんですけど、まさにTTimer的なものなので、それで。

***
LazarusのTBitBtnが.pngを直接指定できることに気づきました。これは便利。いちいち.icoに変換してたのに。

***
ListBoxのオーナードローについて復習しておきます。
オーマードローの時に呼び出されるイベントは、MeasureItemとDrawItemです。
MeasureItemは1行の高さを好きなようにしたい時に、DrawItemは1行に表示する内容を好きなように変えたい時に処理を書くことになります。
まずは、Delphiと同じ感じかどうかを試してみます。

まずは、Styleを変更するところから始めます。

***
ListBox1.Style := lbStandard; の時はこう。
この場合、ListBox1.ItemHeightはフォントのサイズか何かで自動で決まってしまいます。
行間が狭いなぁと思っても我慢することになります。
今回の場合は、ListBox1.ItemHeightは20になって、オブジェクトインスペクタで変更しようとしても20に戻ってしまいます。


***
ListBox1.Style := lbOwnerDrawFixed; の時はこう。
このStyleにすると、ItemHeightを変更できるようになります。自前の描画処理を全く書かなくても、デフォルトの描画処理はちゃんと走るので、使用上の問題は出ません。
ここでは、オブジェクトインスペクタでItemHeightを25にしています。ちょっと広くなってます。


ちなみに、OnDrawItemのイベントハンドラを割り当てると、デフォルトの描画処理がこのハンドラで差し替えられます。

procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
ARect: TRect; State: TOwnerDrawState);
begin
//inherited;を書いてもデフォルトの処理は走りません。
inherited;
end;




要は、真っ白な紙に好きなように描ける状態ということなんですけど、どこに何を描くかを全部自分でやらないといけないので、考えただけでめんどくさくなってきました。

***
ListBox1.Style := lbOwnerDrawVariable; の時はこう。
とりあえず、OnDrawItemのイベントハンドラは消しました。
その代わりに、OnMeasureItemのイベントハンドラにこんなふうに書きました。
procedure TForm1.ListBox1MeasureItem(Control: TWinControl; Index: Integer;
var AHeight: Integer);
begin
AHeight := (Index + 1) * 20;
end;




1行ごとにどの高さで表示するかを、描画の必要があるたびに聞いてくれるので、1行ごとに高さを変更することができます。
OnMeasureItemは、StyleがlbStandardやlbOwnerDrawFixedの時には呼び出されません。
使い方としては、メールの件名をリスト形式で表示したい時とかに、1行に収まり切らない件名は2行に分けて表示するために高くしたり、1行で収まる場合は、省スペース化のために1行分の高さにしたり、というところです。

それか、全部の行は同じ高さでいいけれどもフォントを変更できるようにした場合にも使うと思います。

例えばMSゴシックとメイリオだと、同じサイズでも高さが違うし、フォントのサイズを変更できるようにする場合も1行の高さが違うので、無条件にItemHeight:=25;にしてしまったりすると上下が欠けたりすると思います。

lbStandard;は多分そのへんをうまくしてくれるとおもいますが、自前で描画する内容をいじくりたい時は、高さに関しても面倒を見ないと行けない気がします。

あと、今回はテストなので行ごとに高さを変えましたが、実際にこれをやってしまうと若干操作が鬱陶しくなる気がします。

***
この記事の一番最初に調べたように
・表示のチェックボックス
・アラームまでのカウントダウン
・一言
・ターゲットの日時
・音の名前
か、そのへんを描くにあたって、
・Style:=lbOwnerDrawVariableにして、
・OnMeasureItemで必要な高さを計算して、
・OnDrawItemでゴリゴリ描く
というセオリーコースで行くことにします。

続く。
関連記事
スポンサーサイト
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。