Pebbleアプリ開発メモ

Pebbleアプリ、Watchface開発のメモを残していきます。

【Pebble】公式アラームアプリのようなUIを作成する(角丸+三角バージョン)

f:id:shotsep:20151002163334p:plain

前回の記事で、NumberWindowを使わない数字ピッカーのようなウィンドウの作り方を掲載しました。

pebble.hatenablog.jp

今回は更に公式アラームアプリに近づけて、死角は角丸、選択されている桁には三角をつけて加算/減算ができることをわかりやすく示してみます。

コード中にもありますが、既に追加済みの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);
  }
}