打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Building for Every Pebble // Pebble Developers

BUILDING FOR EVERY PEBBLE
The difference in capabilities between the various Pebble hardware platforms are listed in Hardware Information. For example, the Basalt and Chalk platforms support 64 colors, whereas the Aplite platform only supports two. This can make developing apps with rich color layouts difficult when considering backwards compatibility with older hardware. Another example is using platform-exclusive APIs, such as the PebbleKit JS timeline APIs.

To make life simple for users, developers should strive to write one app that can be used on all platforms. To help make this task simpler for developers, the Pebble SDK provides numerous methods to accommodate different hardware capabilities in code.

Preprocessor Directives

It is possible to specify certain blocks of code to be compiled for specific platforms by using the #ifdef preprocessor statement. For example, the Dictation API should be excluded on platforms with no microphone:

#if defined(PBL_MICROPHONE)
  // Start dictation UI
  dictation_session_start(s_dictation_session);
#else
  // Microphone is not available
  text_layer_set_text(s_some_layer, "Dictation not available!");
#endif
When designing UI layouts, any use of colors on compatible platforms (such as Basalt) can be adapted to either black or white on incompatible platforms (such as Aplite). The PBL_COLOR and PBL_BW symbols will be defined at compile time when appropriate features are available:

#if defined(PBL_COLOR)
  text_layer_set_text_color(s_text_layer, GColorBlack);
  text_layer_set_background_color(s_text_layer, GColorChromeYellow);
#elif defined(PBL_BW)
  text_layer_set_text_color(s_text_layer, GColorWhite);
  text_layer_set_background_color(s_text_layer, GColorBlack);
#endif
This is useful for blocks of multiple statements that change depending on the availability of color support. For single statements, this can also be achieved by using the COLOR_FALLBACK() macro.

window_set_background_color(s_main_window, COLOR_FALLBACK(GColorJaegerGreen, GColorBlack));
See below for a complete list of defines and macros available.

Available Defines and Macros

The tables below show a complete summary of all the defines and associated macros available to conditionally compile or omit feature-dependant code. The macros are well-suited for individual value selection, whereas the defines are better used to select an entire block of code.

Define MACRO Available
PBL_BW PBL_IF_BW_ELSE() Running on hardware that supports only black and white.
PBL_COLOR PBL_IF_COLOR_ELSE() Running on hardware that supports 64 colors.
PBL_MICROPHONE PBL_IF_MICROPHONE_ELSE() Running on hardware that includes a microphone.
PBL_SMARTSTRAP PBL_IF_SMARTSTRAP_ELSE() Running on hardware that includes a smartstrap connector.
PBL_HEALTH PBL_IF_HEALTH_ELSE() Running on hardware that supports Pebble Health and the HealthService API.
PBL_RECT PBL_IF_RECT_ELSE() Running on hardware with a rectangular display.
PBL_ROUND PBL_IF_ROUND_ELSE() Running on hardware with a round display.
PBL_PLATFORM_APLITE None Running on Pebble/Pebble Steel.
PBL_PLATFORM_BASALT None Running on Pebble Time/Pebble Time Steel.
PBL_PLATFORM_CHALK None Running on Pebble Time Round.
PBL_SDK_2 None Compiling with SDK 2.x (deprecated).
PBL_SDK_3 None Compiling with SDK 3.x.
Note: It is strongly recommended to conditionally compile code using applicable feature defines instead of PBL_PLATFORM defines to be as specific as possible.

Avoid Hardcoded Layout Values

With the multiple display shapes and resolutions available, developers should try and avoid hardcoding layout values. This is especially true for Aplite/Basalt apps that are being recompiled for Chalk. Consider the example below:

static void window_load(Window *window) {
  // Create a full-screen Layer - BAD
  s_some_layer = layer_create(GRect(0, 0, 144, 168));
}
The hardcoded width and height of this layer will cover the entire screen on Aplite and Basalt, but not on Chalk. This kind of screen size-dependant calculation should use the bounds of the Window itself:

static void window_load(Window *window) {
  // Get the bounds of the Window
  Layer window_layer = window_get_root_layer(window);
  GRect window_bounds = layer_get_bounds(window_layer);

  // Properly create a full-screen Layer - GOOD
  s_some_layer = layer_create(window_bounds);
}
Another common use of this sort of construction is to make a Layer that is half the screen height. This can also be correctly achieved using the Window's bounds:

GRect layer_bounds = window_bounds;
layer_bounds.size.h /= 2;

// Create a Layer that is half the screen height
s_some_layer = layer_create(layer_bounds);
This approach is also advantageous in simplifying updating an app for a future new screen size, as proportional layout values will adapt as appropriate when the Window's bounds change.

Pebble C WatchInfo

The WatchInfo API can be used to determine exactly which Pebble model and color an app is running on. Apps can use this information to dynamically modify their layout or behavior depending on which Pebble the user is wearing.

For example, the display on Pebble Steel is located at a different vertical position relative to the buttons than on Pebble Time. Any on-screen button hints can be adjusted to compensate for this using WatchInfoModel.

static void window_load(Window *window) {
  Layer window_layer = window_get_root_layer(window);
  GRect window_bounds = layer_get_bounds(window_layer);

  int button_height, y_offset;

  // Conditionally set layout parameters
  switch(watch_info_get_model()) {
    case WATCH_INFO_MODEL_PEBBLE_STEEL:
      y_offset = 64;
      button_height = 44;
      break;
    case WATCH_INFO_MODEL_PEBBLE_TIME:
      y_offset = 58;
      button_height = 56;
      break;

    /* Other cases */

    default:
      y_offset = 0;
      button_height = 0;
      break;

  }

  // Set the Layer frame
  GRect layer_frame = GRect(0, y_offset, window_bounds.size.w, button_height);

  // Create the Layer
  s_label_layer = text_layer_create(layer_frame);
  layer_add_child(window_layer, text_layer_get_layer(s_label_layer));

  /* Other UI code */

}
Developers can also use WatchInfoColor values to theme an app for each available color of Pebble.

static void window_load(Window *window) {
  GColor text_color, background_color;

  // Choose different theme colors per watch color
  switch(watch_info_get_color()) {
    case WATCH_INFO_COLOR_RED:
      // Red theme
      text_color = GColorWhite;
      background_color = GColorRed;
      break;
    case WATCH_INFO_COLOR_BLUE:
      // Blue theme
      text_color = GColorBlack;
      background_color = GColorVeryLightBlue;
      break;

    /* Other cases */

    default:
      text_color = GColorBlack;
      background_color = GColorWhite;
      break;

  }

  // Use the conditionally set value
  text_layer_set_text_color(s_label_layer, text_color);
  text_layer_set_background_color(s_label_layer, background_color);

  /* Other UI code */

}
PebbleKit JS Watch Info

Similar to Pebble C WatchInfo above, the PebbleKit JS Pebble.getActiveWatchInfo() method allows developers to determine which model and color of Pebble the user is wearing, as well as the firmware version running on it. For example, to obtain the model of the watch:

Note: See the section below to avoid problem using this function on older app version.

// Get the watch info
var info = Pebble.getActiveWatchInfo();

console.log('Pebble model: ' + info.model);
Detecting Platform-specific JS Features

A number of features in PebbleKit JS (such as Pebble.timelineSubscribe() and Pebble.getActiveWatchInfo()) exist on SDK 3.x. If an app tries to use any of these on an older Pebble mobile app version where they are not available, the JS app will crash.

To prevent this, be sure to check for the availability of the function before calling it. For example, in the case of Pebble.getActiveWatchInfo():

if (Pebble.getActiveWatchInfo) {
  // Available.
  var info = Pebble.getActiveWatchInfo();

  console.log('Pebble model: ' + info.model);
} else {
  // Gracefully handle no info available

}
Platform-specific Resources

With the availability of color support on Basalt and Chalk, developers may wish to include color versions of resources that had previously been pre-processed for Pebble's black and white display. Including both versions of the resource is expensive from a resource storage perspective, and lays the burden of packing redundant color resources in an Aplite app when built for both platforms.

To solve this problem, the Pebble SDK allows developers to specify which version of an image resource is to be used for each display type, using ~bw or ~color appended to a file name. Resources can also be bundled only with specific platforms using the targetPlatforms property for each resource.

For more details about packaging resources specific to each platform, as well as more tags available similar to ~color, read Platform-specific Resources.

Multiple Display Shapes

With the introduction of the Chalk platform, a new round display type is available with increased pixel resolution. To distinguish between the two possible shapes of display, developers can use defines to conditionally include code segments:

#if defined(PBL_RECT)
  printf("This is a rectangular display!");
#elif defined(PBL_ROUND)
  printf("This is a round display!");
#endif
Another approach to this conditional compilation is to use the PBL_IF_RECT_ELSE() and PBL_IF_ROUND_ELSE() macros, allowing values to be inserted into expressions that might otherwise require a set of #define statements similar to the previous example. This would result in needless verbosity of four extra lines of code when only one is actually needed. These are used in the following manner:

// Conditionally print out the shape of the display
printf("This is a %s display!", PBL_IF_RECT_ELSE("rectangular", "round"));
This mechanism is best used with window bounds-derived layout size and position value. See the Avoid Hardcoded Layout Values section above for more information. Making good use of the builtin Layer types will also help safeguard apps against display shape and size changes.

Another thing to consider is rendering text on a round display. Due to the rounded corners, each horizontal line of text will have a different available width, depending on its vertical position.

 

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
iOS截屏代码
iOS仿照微信之检测用户截屏, 并获取所截图片
MeeGo体系结构
逐笔逐单分时指标
水滴石穿之页面遮罩层实现、向window.open()打开的窗口POST数据
Car Adornment Article Exterior Chapter--Membrane 2
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服