2016年01月12日

Pebble Time用のWatchFaceのサンプルを作った。

Pebble Time用のWatchFaceのサンプルを作った。

・画像の表示
・月/日 時:分の表示
・バッテリー残量の表示
・Bluetooth状態の表示/接続・切断時バイブ

と、基本的に欲しい機能を突っ込みました。
ほとんど公式のチュートリアル通りです。


プロジェクトのファイルを置いておくので、CloudPebbleにインポートすれば
あとは背景画像を差し替えるだけで使えると思います。
Pebble Classicでも使えるとは思いますが、動作確認はしていませんし、
動くようにも作っていません。(各オプションがPebble Time用になっています)

ダウンロード


動画を見ながらどうぞ。(3:40から手順解説になります)


以下ソースコード。

#include <pebble.h>
#include "main.h"

//うまくWatchFaceに登録されない時は、一度スマホからこのWatchFaceを削除したり
//UUIDやバージョン、作者名を変更したりすると良い。

//mainウィンドウポインタ
static Window *s_main_window;
//時間表示用文字列レイヤー
static TextLayer *s_time_layer;
static TextLayer *sw_time_layer;

//バッテリー表示レイヤー
static TextLayer *s_bat_layer;

//ビットマップ表示用レイヤー
static BitmapLayer *s_background_layer;
//ビットマップデータポインタ
static GBitmap *s_background_bitmap;

//Bluetoothステータス
static char bt_status[4] = "BT";
//過去のBluetoothステータス
static int bt_st_old = 1;

//バッテリーハンドラ
static void battery_handler(BatteryChargeState new_state) {
//バッテリー状態取得して表示(ついでにBluetooth接続状態を表示)
static char s_battery_buffer[32];
snprintf(s_battery_buffer, sizeof(s_battery_buffer), "Bat: %d%% %s", new_state.charge_percent,bt_status);
text_layer_set_text
(s_bat_layer, s_battery_buffer);
}

//Bluetoothハンドラ
void bt_handler(bool connected) {
if (connected) {
//接続に変化したらバイブ
if(bt_st_old == 0)
vibes_short_pulse
();
bt_st_old
= 1;
snprintf(bt_status,4,"BT");
} else {
//切断に変化したらバイブ
if(bt_st_old == 1)
vibes_short_pulse
();
bt_st_old
= 0;
snprintf(bt_status,4,"--");
}
//現在のバッテリーを読む(BT表示)
battery_handler
(battery_state_service_peek());
}

//画面更新
static void update_time() {
//時刻構造体を得る
time_t temp = time(NULL);
//ローカル時刻を得る
struct tm *tick_time = localtime(&temp);

//文字列バッファを確保し、そこに文字列形式で時刻を得る。
//24時間表示かどうかで切り替えている。
static char s_buffer[8];
strftime(s_buffer, sizeof(s_buffer), clock_is_24h_style() ?
"%H:%M" : "%I:%M", tick_time);
static char sp_buffer[16];
snprintf(sp_buffer,16,"%02d/%02d %s",
(tick_time->tm_mon+1),
tick_time
->tm_mday,
s_buffer
);

//テキストレイヤーにセットする
text_layer_set_text
(s_time_layer, sp_buffer);
text_layer_set_text
(sw_time_layer, sp_buffer);


}


//タイマーハンドラ
static void tick_handler(struct tm *tick_time, TimeUnits units_changed) {
update_time
();//1分に1回画面更新する
}

//Windowが生成された時
static void main_window_load(Window *window) {
//ウィンドウの情報を取得
Layer
*window_layer = window_get_root_layer(window);
GRect bounds
= layer_get_bounds(window_layer);

//ビットマップデータの読み込み
//RESOURCESではRESOURCE_ID_を含めない名前で指定する。
//この場合。IDENTIFIER=BACKGROUND
s_background_bitmap
= gbitmap_create_with_resource(RESOURCE_ID_BACKGROUND);
//ビットマップレイヤーの作成
s_background_layer
= bitmap_layer_create(bounds);
//ビットマップレイヤーにビットマップを割り
bitmap_layer_set_bitmap(s_background_layer, s_background_bitmap);
//windowレイヤーに子レイヤーとしてビットマップレイヤーを追加
layer_add_child
(window_layer, bitmap_layer_get_layer(s_background_layer));

//-------------------------------------

//境界付きでテキストレイヤーを作成
sw_time_layer = text_layer_create(
//x, y, w , h
GRect
(1, 111, bounds.size.w, 50)

//PBL_IF_ROUND_ELSE(if_true, if_false)なので、円形ならx=58,角形ならx=52
//GRect(0, PBL_IF_ROUND_ELSE(58, 52), bounds.size.w, 50)
);

//テキストレイヤーを設定
text_layer_set_background_color
(sw_time_layer, GColorClear);
text_layer_set_text_color
(sw_time_layer, GColorFromHEX(0x000000));
//text_layer_set_text(s_time_layer, "00:00");
text_layer_set_font
(sw_time_layer, fonts_get_system_font(FONT_KEY_GOTHIC_28));
text_layer_set_text_alignment
(sw_time_layer, GTextAlignmentCenter);

//windowレイヤーに子レイヤーとしてテキストレイヤーを追加
layer_add_child
(window_layer, text_layer_get_layer(sw_time_layer));

//-------------------------------------

//境界付きでテキストレイヤーを作成
s_time_layer = text_layer_create(
//x, y, w , h
GRect
(0, 110, bounds.size.w, 50)

//PBL_IF_ROUND_ELSE(if_true, if_false)なので、円形ならx=58,角形ならx=52
//GRect(0, PBL_IF_ROUND_ELSE(58, 52), bounds.size.w, 50)
);

//テキストレイヤーを設定
text_layer_set_background_color
(s_time_layer, GColorClear);
text_layer_set_text_color
(s_time_layer, GColorFromHEX(0xFFFFFF));
//text_layer_set_text(s_time_layer, "00:00");

text_layer_set_font
(s_time_layer, fonts_get_system_font(FONT_KEY_GOTHIC_28));
text_layer_set_text_alignment
(s_time_layer, GTextAlignmentCenter);

//windowレイヤーに子レイヤーとしてテキストレイヤーを追加
layer_add_child
(window_layer, text_layer_get_layer(s_time_layer));

//-------------------------------------

//境界付きでテキストレイヤーを作成
s_bat_layer
= text_layer_create(
//x, y, w , h
GRect
(0, 140, bounds.size.w, 50)

//PBL_IF_ROUND_ELSE(if_true, if_false)なので、円形ならx=58,角形ならx=52
//GRect(0, PBL_IF_ROUND_ELSE(58, 52), bounds.size.w, 50)
);

//テキストレイヤーを設定
text_layer_set_background_color
(s_bat_layer, GColorClear);
text_layer_set_text_color
(s_bat_layer, GColorFromHEX(0xFFFFFF));
//text_layer_set_text(s_time_layer, "00:00");

text_layer_set_font
(s_bat_layer, fonts_get_system_font(FONT_KEY_GOTHIC_14));
text_layer_set_text_alignment
(s_bat_layer, GTextAlignmentCenter);

//windowレイヤーに子レイヤーとしてテキストレイヤーを追加
layer_add_child
(window_layer, text_layer_get_layer(s_bat_layer));

//---------------------

//タイマーサービスに分単位での更新を登録する。
tick_timer_service_subscribe
(MINUTE_UNIT, tick_handler);

//バッテリー状態サービスに登録する
battery_state_service_subscribe
(battery_handler);
//現在のバッテリーを読む
battery_handler
(battery_state_service_peek());

//Bluetooth接続状態サービスに登録する
connection_service_subscribe
((ConnectionHandlers){
.pebble_app_connection_handler = bt_handler
}
);
}

//Windowが破棄された時
static void main_window_unload(Window *window) {
//ビットマップデータを破棄
gbitmap_destroy
(s_background_bitmap);
//ビットマップレイヤーを破棄
bitmap_layer_destroy
(s_background_layer);
//テキストレイヤーを破棄
text_layer_destroy
(s_time_layer);
}

//Appの読み込み時
static void init() {
//Windowエレメントを作成し、ポインタに割り付け
s_main_window
= window_create();

//背景色を黒色に設定
window_set_background_color
(s_main_window, GColorCyan);

//ウィンドウハンドラを割り付け
window_set_window_handlers
(s_main_window, (WindowHandlers){
.load = main_window_load,
.unload = main_window_unload
}
);

//スタックにプッシュし表示。アニメーション有効=true
window_stack_push
(s_main_window, true);
//この時点でmain_window_loadが呼ばれる?

//時刻を初期設定する。
update_time
();
}

static void deinit() {
//ウィンドウを破棄
window_destroy
(s_main_window);
}

int main(void) {
init
();
app_event_loop
();
deinit
();
}
posted by gpsnmeajp at 00:38| Comment(0) | TrackBack(0) | 未分類
この記事へのコメント
コメントを書く
お名前: [必須入力]

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
この記事へのトラックバックURL
http://blog.sakura.ne.jp/tb/181155319
※言及リンクのないトラックバックは受信されません。

この記事へのトラックバック