【Pebble】公式アラームアプリのようなUIを作成する(角丸+三角バージョン)
前回の記事で、NumberWindowを使わない数字ピッカーのようなウィンドウの作り方を掲載しました。
今回は更に公式アラームアプリに近づけて、死角は角丸、選択されている桁には三角をつけて加算/減算ができることをわかりやすく示してみます。
コード中にもありますが、既に追加済みのTextLayerのBoundsを取ろうとして
layer_get_bounds(text_layer_get_layer(ampmBox));
とやると座標が(0,0)になっちゃうんですよね。なんでだろ。
角丸バージョン
#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", }; Layer *round_rect_layer; GPath *triangle_up, *triangle_down; GPathInfo triangleUp01PI = { 3, (GPoint []){ {42, 36}, {56, 36}, {49, 28} } }; GPathInfo triangleDown01PI = { 3, (GPoint []){ {42, 78}, {56, 78}, {49, 86} } }; GPathInfo triangleUp02PI = { 3, (GPoint []){ {42 + 48, 36}, {56 + 48, 36}, {49 + 48, 28} } }; GPathInfo triangleDown02PI = { 3, (GPoint []){ {42 + 48, 78}, {56 + 48, 78}, {49 + 48, 86} } }; GPathInfo triangleUp03PI = { 3, (GPoint []){ {42 + 24, 36 + 47}, {56 + 24, 36 + 47}, {49 + 24, 28 + 47} } }; GPathInfo triangleDown03PI = { 3, (GPoint []){ {42 + 24, 78 + 47}, {56 + 24, 78 + 47}, {49 + 24, 86 + 47} } }; static void draw_roundrect_and_triangle(Layer *layer, GContext *ctx) { if(boxIndex < 2) { graphics_fill_rect(ctx, GRect(29 + (boxIndex * 48), 40 , 40, 35), 4, GCornersAll); text_layer_set_text_color(numBox[boxIndex], GColorWhite); if(boxIndex == 0) { triangle_up = gpath_create(&triangleUp01PI); triangle_down = gpath_create(&triangleDown01PI); } else { triangle_up = gpath_create(&triangleUp02PI); triangle_down = gpath_create(&triangleDown02PI); } gpath_draw_filled(ctx, triangle_up); gpath_draw_filled(ctx, triangle_down); } else { //graphics_fill_rect(ctx, layer_get_bounds(text_layer_get_layer(ampmBox)), 4, GCornersAll); // 座標が(0,0)になる graphics_fill_rect(ctx, GRect(47, 87, 50, 35), 4, GCornersAll); text_layer_set_text_color(numBox[boxIndex], GColorWhite); triangle_up = gpath_create(&triangleUp03PI); triangle_down = gpath_create(&triangleDown03PI); gpath_draw_filled(ctx, triangle_up); gpath_draw_filled(ctx, triangle_down); } } void window_load(Window *window) { Layer *window_layer = window_get_root_layer(window); GRect bounds = layer_get_bounds(window_layer); round_rect_layer = layer_create(bounds); layer_add_child(window_layer, round_rect_layer); layer_set_update_proc(round_rect_layer, draw_roundrect_and_triangle); for (int i = 0; i < NUMBER_COUNT; i++) { numBox[i] = text_layer_create(GRect(29 + (i * 48), 40 , 40, 35)); text_layer_set_background_color(numBox[i], GColorClear); 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])); } ampmBox = text_layer_create(GRect(47, 87, 50, 35)); text_layer_set_background_color(ampmBox, GColorClear); 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++; layer_set_update_proc(round_rect_layer, draw_roundrect_and_triangle); if(boxIndex < 2) { for (int i = 0; i < NUMBER_COUNT; i++) { text_layer_set_text_color(numBox[i], GColorBlack); } text_layer_set_text_color(numBox[boxIndex], GColorWhite); } else if(boxIndex == 2) { for (int i = 0; i < NUMBER_COUNT; i++) { text_layer_set_text_color(numBox[i], GColorBlack); } text_layer_set_text_color(ampmBox, GColorWhite); } else { boxIndex = 0; text_layer_set_text_color(numBox[boxIndex], GColorWhite); 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); } }