【Pebble】公式アラームアプリのようなUIを作成する
以前に紹介したCurrency Converter。海外から買い物をする機会が多いので重宝してます。
そもそも作ろうと思ったきっかけは、ストアにいいUIのコンバーターがなかったからでした。
Currency ConverterのUI
公式のアラームアプリのような、中心のボタンで桁を選択、上ボタン/下ボタンで加算/減算をするUIです。
ご存知の通りPebbleにはタッチスクリーンが搭載されていないので、UIは他のデバイスと違う方法でアプローチしないといけません。
調べていたところ、Number Windowというクラスを使うと実現できそうだったのですが、どうも1桁しかおけないようなので自作しました。
NumberWindow不使用で実現
#include <pebble.h> #define NUMBER_COUNT 2 static void up_click_handler(ClickRecognizerRef recognizer, void *context); static void select_click_handler(ClickRecognizerRef recognizer, void *context); static void down_click_handler(ClickRecognizerRef recognizer, void *context); static void click_config_provider(void *context); Window *window; TextLayer *numBox[NUMBER_COUNT]; char c[NUMBER_COUNT][4]; uint8_t boxIndex = 0; TextLayer *ampmBox; char ampmChar[8]; uint8_t ampmIndex = 0; char currencyNameArray[2][6] = {"AM", "PM", }; void window_load(Window *window) { for (int i = 0; i < NUMBER_COUNT; i++) { numBox[i] = text_layer_create(GRect(29 + (i * 48), 40 , 40, 35)); text_layer_set_font(numBox[i], fonts_get_system_font(FONT_KEY_GOTHIC_28_BOLD)); text_layer_set_text_alignment(numBox[i] , GTextAlignmentCenter); snprintf(c[i], sizeof(c[i]), "%02d", 0); text_layer_set_text(numBox[i], c[i]); layer_add_child(window_get_root_layer(window), text_layer_get_layer(numBox[i])); } text_layer_set_background_color(numBox[boxIndex], GColorBlack); text_layer_set_text_color(numBox[boxIndex], GColorWhite); ampmBox = text_layer_create(GRect(47, 87, 50, 30)); text_layer_set_font(ampmBox, fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD)); text_layer_set_text_alignment(ampmBox , GTextAlignmentCenter); snprintf(ampmChar, sizeof(ampmChar), "%s", currencyNameArray[0]); text_layer_set_text(ampmBox, ampmChar); layer_add_child(window_get_root_layer(window), text_layer_get_layer(ampmBox)); } void window_unload(Window *window) { } void init(void) { window = window_create(); window_set_background_color(window, GColorWhite); window_set_window_handlers(window, (WindowHandlers) { .load = window_load, .unload = window_unload }); window_stack_push(window, true); window_set_click_config_provider(window, click_config_provider); } void deinit(void) { window_destroy(window); } int main(void) { init(); app_event_loop(); deinit(); } static void click_config_provider(void *context) { window_single_click_subscribe(BUTTON_ID_UP, up_click_handler); window_single_click_subscribe(BUTTON_ID_SELECT, select_click_handler); window_single_click_subscribe(BUTTON_ID_DOWN, down_click_handler); } static void select_click_handler(ClickRecognizerRef recognizer, void *context) { boxIndex++; if(boxIndex < 2) { for (int i = 0; i < NUMBER_COUNT; i++) { text_layer_set_background_color(numBox[i], GColorClear); text_layer_set_text_color(numBox[i], GColorBlack); } text_layer_set_background_color(numBox[boxIndex], GColorBlack); text_layer_set_text_color(numBox[boxIndex], GColorWhite); } else if(boxIndex == 2) { for (int i = 0; i < NUMBER_COUNT; i++) { text_layer_set_background_color(numBox[i], GColorClear); text_layer_set_text_color(numBox[i], GColorBlack); } text_layer_set_background_color(ampmBox, GColorBlack); text_layer_set_text_color(ampmBox, GColorWhite); } else { boxIndex = 0; text_layer_set_background_color(numBox[boxIndex], GColorBlack); text_layer_set_text_color(numBox[boxIndex], GColorWhite); text_layer_set_background_color(ampmBox, GColorClear); text_layer_set_text_color(ampmBox, GColorBlack); } } static void up_click_handler(ClickRecognizerRef recognizer, void *context) { if(boxIndex < 2) { int current = atoi(text_layer_get_text(numBox[boxIndex])); current = (current < 12) ? current + 1 : 0; snprintf(c[boxIndex], sizeof(c[boxIndex]), "%02d", current); text_layer_set_text(numBox[boxIndex], c[boxIndex]); } else if(boxIndex == 2) { ampmIndex = (ampmIndex > 0) ? ampmIndex - 1 : 1; snprintf(ampmChar, sizeof(ampmChar), "%s", currencyNameArray[ampmIndex]); text_layer_set_text(ampmBox, ampmChar); } } static void down_click_handler(ClickRecognizerRef recognizer, void *context) { if(boxIndex < 2) { int current = atoi(text_layer_get_text(numBox[boxIndex])); current = (current > 0) ? current - 1 : 12; snprintf(c[boxIndex], sizeof(c[boxIndex]), "%02d", current); text_layer_set_text(numBox[boxIndex], c[boxIndex]); } else if(boxIndex == 2) { ampmIndex = (ampmIndex < 1) ? ampmIndex + 1 : 0; snprintf(ampmChar, sizeof(ampmChar), "%s", currencyNameArray[ampmIndex]); text_layer_set_text(ampmBox, ampmChar); } }