T time

プログラミングや電子工作、各種ガジェットに関するブログです。

PebbleTime 開発 - デジタル時計を作る

前回 は Watchface の HelloWorld を見てみました。

今回は、このコードを修正してデジタル時計を作って見ます。 いよいよ Watchface らしくなってきました。

今回のゴール

今回は秒単位で現在時刻を表示するデジタル時計を作ります。 以下の様な見た目になります。

f:id:tatur0u:20150705205329p:plain

コード

これが今回作成するコードの全てです。

前回からの変更点

以下が、前回のコードからの変更点の概要です。

  • window
    • 変更なし
  • text_layer
    • サイズを 144x155 から 144x168 に変更
    • 文字色を白に変更
    • 背景色を赤に変更
  • TickTimerService
    • 1 秒ごとに現在時刻を設定する処理を追加

text_layer の変更点

TextLayer 型のオブジェクトは、以下を設定可能です。

設定項目 使用するAPI 備考
表示するテキスト text_layer_set_text 文字はコピーされないので、グローバル変数を指定する必要があります。
背景色 text_layer_set_background_color GColorXXX を設定可能です。色数は64色です。
文字色 text_layer_set_text_color 背景色と同じです。
オーバーフローモード text_layer_set_overflow_mode 文字列がレイヤーのサイズを超えた場合の設定。
フォント text_layer_set_font 組み込みのフォントと、好きな TrueType font を表示可能です。
アライメント text_layer_set_text_alignment 左寄せ、中寄せ、右寄せ が設定可能です。
レイヤーサイズ text_layer_set_size レイヤーの大きさを後から変更可能です。

これらを使用して、いろいろ設定していきます。

それではコードを解説していきます。

サイズを 144x155 から 144x168 に変更

text_layer のサイズを画面いっぱいのサイズに変更しました。 デフォルトサイズが何故か少し小さかったので*1、画面いっぱいに広げました。

void handle_init(void) {
    ...    
    // text_layer を作成
    text_layer = text_layer_create(GRect(0, 0, 144, 168));
    ...
}

文字色を白に、背景色を赤に変更

せっかく PebbleTime はカラー表示ができるようになったので、赤白にしましょう。 ウルトラマンと同じです。

void handle_init(void) {
    ...    
    // text_layer の文字色を 白 に設定
    text_layer_set_text_color(text_layer, GColorWhite);

    // text_layer の背景色を 赤 に設定
    text_layer_set_background_color(text_layer, GColorRed);
    ...
}

色は「GColor + 色」で指定します。白なら GColorWhite 、赤なら GColorRed です。

TickTimerService

TickTimerService は、 一定間隔で指定の関数(ハンドラ)を呼び出すサービスです。

以下のAPIを使用します。

void tick_timer_service_subscribe( TimeUnits tick_units, TickHandler handler )

http://developer.getpebble.com/docs/c/Foundation/Event_Service/TickTimerService/#tick_timer_service_subscribe

第1引数 tick_units には以下の値を設定します。

設定値 意味
SECOND_UNIT 1 秒間隔
MINUTE_UNIT 1 分間隔
HOUR_UNIT 1 時間間隔
DAY_UNIT 1 日間隔
MONTH_UNIT 1 ヶ月間隔
YEAR_UNIT 1 年間隔

なお、この関数を複数回実行すると前回の設定が上書きされます。 そのため、複数の間隔を設定する場合は、設定値を OR した値を設定します。

たとえば、1時間間隔 と 1日間隔で関数を呼び出したい場合は、以下のように設定します。

tick_timer_service_subscribe( HOUR_UNIT | DAY_UNIT, handler );

第2引数 handler には以下の型の関数を設定します。

typedef void (*TickHandler) ( struct tm *tick_time, TimeUnits units_changed )

http://developer.getpebble.com/docs/c/Foundation/Event_Service/TickTimerService/#TickHandler

ハンドラの第1引数 tick_time には、ハンドラが呼び出された時の時刻が struct tm 型で渡ってきます。

struct tm { 
    int tm_sec;     // 秒(0〜60)
    int tm_min;     // 分(0〜59)
    int tm_hour;    // 時間(0〜23)
    int tm_mday;    // 日(1〜31)
    int tm_mon;     // 月(0〜11)
    int tm_year;    // 年(1900からの通算)
    int tm_wday;    // 曜日(0〜6、日曜日=0)
    int tm_yday;    // 年内通算日(0〜365、1月1日=0)
    int tm_isdst;   // 夏時間(夏時間である=1、夏時間ではない=0、夏時間などない=-1)
    int tm_gmtoff;  // UTCからのオフセット秒
    char tm_zone[TZ_LEN]; // タイムゾーン
};

ハンドラの第2引数 units_changed には、tick_timer_service_subscribe の第1引数に設定した値が渡ってきます。 上の例では HOUR_UNITDAY_UNIT が渡ってくるので、以下のように処理します。

void handler (struct tm *tick_time, TimeUnits units_changed) {
    if (units_changed & HOUR_UNIT) {
        // 1時間ごとの処理
    } else if (units_changed & DAY_UNIT) {
        // 1日ごとの処理
    }
}

1 秒ごとに現在時刻を設定する処理を追加

この Watchface は秒単位で現在時刻を表示するので、TickTimerService を使用して 1 秒ごとにハンドラを呼び出します。

void handle_init(void) {
    ...
    // TickTimerService を使用して 1 秒ごとにハンドラが呼ばれるように設定
    tick_timer_service_subscribe(SECOND_UNIT, tick_handler);
    ...
}

tick_handler の定義は以下です。

#define TEXT_LEN (32)
char text[TEXT_LEN + 1];

// TickTimerService ハンドラ(1 秒ごとに呼ばれる)
void tick_handler(struct tm *tick_time, TimeUnits units_changed) {
    // 表示する文字を作成
    strftime(text, TEXT_LEN, "%Y-%m-%d%n%H:%M:%S", tick_time);

    // 表示する文字を text_layer に設定
    text_layer_set_text(text_layer, text);

    // ログを表示
    APP_LOG(APP_LOG_LEVEL_DEBUG, text);
}

text_layer_set_text 関数に設定する文字列 text は、グローバル変数で定義しておきます。

そして、表示する文字列(時間)は、strftime 関数で作成しました。

int strftime(char * s, size_t maxsize, const char * format, const struct tm * tm_p)

http://developer.getpebble.com/docs/c/Standard_C/Time/#strftime

この関数は、printf のようにフォーマットを指定して文字列を作成します。 オンラインドキュメントを見ても strftime の仕様は描いてないですが、C標準関数なのでman pageを参照してください。

動作確認

以前の記事のとおり、コンパイルしてエミュレータに実行イメージを転送してください。

現在時刻が表示され、1 秒ごとに表示が更新されるはずです。

あとがき

今回は、HelloWorld を修正してデジタル時計を作ってみました。

見た目はともかく、ちゃんと時計として機能するものができました。 このように、Watchface を作るのはそれほど難しくないです。 あとは文字の場所を変えて背景をつければ自分だけの Watchface を作ることができますね。

次回は、画像を表示してみたいと思います。


PebbleTime は、公式サイトでプレオーダーを受付中です。 2015-07-06 現在で $199.99 です。

getpebble.com


Amazon.co.jp並行輸入品が出てますね。 ただ、正直高いです。 公式サイトで買うことをおすすめします。


こちらは古い白黒のやつ。 見た目の違いで2種類あります(性能は同じ)。

Pebble Steel (Brushed Stainless)

Pebble Steel (Brushed Stainless)

*1:初代Pebbleはステータスバーの分だけ縦幅が少し狭かったので、それの名残かもしれません。