Privacy Policy ยท Cookie Policy
  • Home
  • Tutorials
  • Get the SDK
  • Guides
  • Documentation
  • Examples
  • Community
  • Blog
  • More
  • Tutorials
  • Learn C Basics
  • Create a C Watchface
  • Create a JS Watchapp
  • Add More Features
  • Go Beyond
  • PebbleKit Android Tutorial
  • PebbleKit iOS Tutorial
  • Learn C Basics
  • Learning C for the Pebble SDK
  • A Simple C Program
  • Hello, Pebble!
  • More C Concepts
  • Create a C Watchface
  • Build Your Own Watchface
  • Customize Your Watchface
  • Adding Content From The Web
  • Create a JS Watchapp
  • Build A Watchapp with Pebble.js
  • Expanded Weather Forecasts
  • Adding More Details
  • Add More Features
  • Add a Date View
  • Add a Battery Meter
  • Add Connection Alerts
  • Go Beyond
  • Vector Animations
  • PebbleKit Android Tutorial
  • Integrating with Android
  • Controlling Apps From Pebble
  • Rock, Paper, Scissors with Pebble
  • PebbleKit iOS Tutorial
  • Integrating with iOS
  • Controlling Apps From Pebble
  • Rock, Paper, Scissors with Pebble
  • Guides
  • App Resources
  • Appstore Publishing
  • Best Practices
  • Communication
  • Debugging
  • Design and Interaction
  • Events and Services
  • Graphics and Animations
  • Migrating Older Apps
  • Pebble Packages
  • Pebble Timeline
  • Smartstraps
  • Tools and Resources
  • User Interfaces
  • App Resources
  • Animated Images
  • App Assets
  • Converting SVG to PDC
  • Fonts
  • Images
  • Pebble Draw Command File Format
  • Platform-specific Resources
  • Raw Data Files
  • System Fonts
  • Appstore Publishing
  • Appstore Analytics
  • Appstore Assets
  • Preparing a Submission
  • Publishing an App
  • iOS App Whitelisting
  • Best Practices
  • Building for Every Pebble
  • Conserving Battery Life
  • Modular App Architecture
  • Communication
  • Advanced Communication
  • Datalogging
  • Sending and Receiving Data
  • PebbleKit Android
  • PebbleKit iOS
  • PebbleKit JS
  • Sports API
  • Debugging
  • Common Runtime Errors
  • Common Syntax Errors
  • Debugging with App Logs
  • Debugging with GDB
  • Design and Interaction
  • Benefits of Design Guidelines
  • Core Experience Design
  • Example Implementations
  • Round App Design
  • One Click Actions
  • Recommended Guidelines and Patterns
  • Events and Services
  • Accelerometer
  • Background Worker
  • Buttons
  • Compass
  • Dictation
  • Event Services
  • Pebble Health
  • Persistent Storage
  • Wakeups
  • Graphics and Animations
  • Animations
  • Drawing Primitives, Images and Text
  • Framebuffer Graphics
  • Vector Graphics
  • Migrating Older Apps
  • SDK 3.x on Aplite Migration Guide
  • SDK 3.x Migration Guide
  • SDK 4.x Migration Guide
  • SDK 2.x Migration Guide
  • PebbleKit iOS 3.0 Migration Guide
  • Pebble Packages
  • Creating Pebble Packages
  • Using Pebble Packages
  • Pebble Timeline
  • Creating Pins
  • Service Architecture
  • Managing Subscriptions
  • Libraries for Pushing Pins
  • Public Web API
  • Smartstraps
  • Hardware Specification
  • Protocol Specification
  • Talking To Pebble
  • Talking To Smartstraps
  • Tools and Resources
  • App Metadata
  • CloudPebble
  • Color Picker Tool
  • Developer Connection
  • Hardware Information
  • Internationalization
  • Command Line Tool
  • User Interfaces
  • App Configuration
  • App Exit Reason
  • AppGlance C API
  • AppGlance in PebbleKit JS
  • AppGlance REST API
  • Layers
  • Round App UI
  • Unobstructed Area
  • Documentation
  • Pebble C
  • Pebble JavaScript API (beta)
  • PebbleKit JavaScript
  • PebbleKit iOS
  • PebbleKit Android
  • Pebble C
  • Pebble JavaScript API (beta)
  • PebbleKit JavaScript
  • PebbleKit iOS
  • PebbleKit Android
  • Community
  • Events
  • Online Communities
  • Example Apps
  • Tools
  • Libraries
  • Events
  • Developer Retreat 2014
  • Developer Retreat 2015
  • Example Apps
  • Hello
  • Caltrain
  • HeroBoard
  • Multi Timer
  • Resistor Time
  • Tools
  • App Message Bridge
  • Appstore Badge Generator
  • GPath.svg
  • pBuild Travis CI Build Tool
  • Sublime Text Plugin
  • Watchface Generator
  • Watch Status
  • Libraries
  • Color Selector
  • Custom Status Bar for Pebble
  • EffectLayer
  • GBitmap Colour Palette Manipulator
  • Java Pebble Timeline
  • JS Message Queue
  • Pebble Timeline API for DotNet (C#)
  • Pebble API PHP
  • PebbleTimeline API Ruby
  • PHPebbleTimeline
  • PinPusher
  • pypebbleapi
  • Simple Dithering Library
  • T3 Keyboard
  • ToastLayer Library
  • More
  • Examples
  • App Inspiration
  • Contact
  • Build Tools
pebble
  • Tutorials
  • Get the SDK
  • Guides
  • Documentation
  • Examples
  • Community
  • Blog
  • More
Privacy
Cookies
Publish

Guides

  • Table of Contents
  • App Resources
  • Appstore Publishing
  • Best Practices
  • Communication
  • Debugging
  • Design and Interaction
  • Events and Services
    • Accelerometer
    • Background Worker
    • Buttons
    • Compass
    • Dictation
    • Event Services
    • Heart Rate Monitor
    • Pebble Health
    • Persistent Storage
    • Wakeups
  • Graphics and Animations
  • Migrating Older Apps
  • Pebble Packages
  • Pebble Timeline
  • Rocky.js
  • Smartstraps
  • Tools and Resources
  • User Interfaces

Buttons

Button Clicks are the primary input method on Pebble. All Pebble watches come with the same buttons available, shown in the diagram below for Pebble Time:

button-layout

These buttons are used in a logical fashion throughout the system:

  • Back - Navigates back one Window until the watchface is reached.

  • Up - Navigates to the previous item in a list, or opens the past timeline when pressed from the watchface.

  • Select - Opens the app launcher from the watchface, accepts a selected option or list item, or launches the next Window.

  • Down - Navigates to the next item in a list, or opens the future timeline when pressed from the watchface.

Developers are highly encouraged to follow these patterns when using button clicks in their watchapps, since users will already have an idea of what each button will do to a reasonable degree, thus avoiding the need for lengthy usage instructions for each app. Watchapps that wish to use each button for a specific action should use the ActionBarLayer or ActionMenu to give hints about what each button will do.

Listening for Button Clicks

Button clicks are received via a subscription to one of the types of button click events listed below. Each Window that wishes to receive button click events must provide a ClickConfigProvider that performs these subscriptions.

The first step is to create the ClickConfigProvider function:

static void click_config_provider(void *context) {
  // Subcribe to button click events here

}

The second step is to register the ClickConfigProvider with the current Window, typically after window_create():

// Use this provider to add button click subscriptions
window_set_click_config_provider(window, click_config_provider);

The final step is to write a ClickHandler function for each different type of event subscription required by the watchapp. An example for a single click event is shown below:

static void select_click_handler(ClickRecognizerRef recognizer, void *context) {
  // A single click has just occured

}

Types of Click Events

There are five types of button click events that apps subscribe to, enabling virtually any combination of up/down/click events to be utilized in a watchapp. The usage of each of these is explained below:

Single Clicks

Most apps will use this type of click event, which occurs whenever the button specified is pressed and then immediately released. Use window_single_click_subscribe() from a ClickConfigProvider function, supplying the ButtonId value for the chosen button and the name of the ClickHandler that will receive the events:

static void click_config_provider(void *context) {
  ButtonId id = BUTTON_ID_SELECT;  // The Select button

  window_single_click_subscribe(id, select_click_handler);
}

Single Repeating Clicks

Similar to the single click event, the single repeating click event allows repeating events to be received at a specific interval if the chosen button is held down for a longer period of time. This makes the task of scrolling through many list items or incrementing a value significantly easier for the user, and uses fewer button clicks.

static void click_config_provider(void *context) {
  ButtonId id = BUTTON_ID_DOWN;       // The Down button
  uint16_t repeat_interval_ms = 200;  // Fire every 200 ms while held down

  window_single_repeating_click_subscribe(id, repeat_interval_ms,
                                                down_repeating_click_handler);
}

After an initial press (but not release) of the button id subscribed to, the callback will be called repeatedly with an interval of repeat_interval_ms until it is then released.

Developers can determine if the button is still held down after the first callback by using click_recognizer_is_repeating(), as well as get the number of callbacks counted so far with click_number_of_clicks_counted():

static void down_repeating_click_handler(ClickRecognizerRef recognizer,
                                                              void *context) {
  // Is the button still held down?
  bool is_repeating = click_recognizer_is_repeating(recognizer);

  // How many callbacks have been recorded so far?
  uint8_t click_count = click_number_of_clicks_counted(recognizer);
}

Single click and single repeating click subscriptions conflict, and cannot be registered for the same button.

Multiple Clicks

A multi click event will call the ClickHandler after a specified number of single clicks has been recorded. A good example of usage is to detect a double or triple click gesture:

static void click_config_provider(void *context) {
  ButtonId id = BUTTON_ID_SELECT;  // The Select button
  uint8_t min_clicks = 2;          // Fire after at least two clicks
  uint8_t max_clicks = 3;          // Don't fire after three clicks
  uint16_t timeout = 300;          // Wait 300ms before firing
  bool last_click_only = true;     // Fire only after the last click

  window_multi_click_subscribe(id, min_clicks, max_clicks, timeout,
                                 last_click_only, multi_select_click_handler);
}

Similar to the single repeating click event, the ClickRecognizerRef can be used to determine how many clicks triggered this multi click event using click_number_of_clicks_counted().

Long Clicks

A long click event is fired after a button is held down for the specified amount of time. The event also allows two ClickHandlers to be registered - one for when the button is pressed, and another for when the button is released. Only one of these is required.

static void click_config_provider(void *context) {
  ButtonId id = BUTTON_ID_SELECT;  // The select button
  uint16_t delay_ms = 500;         // Minimum time pressed to fire

  window_long_click_subscribe(id, delay_ms, long_down_click_handler,
                                                       long_up_click_handler);
}

Raw Clicks

The last type of button click subcsription is used to track raw button click events. Like the long click event, two ClickHandlers may be supplied to receive each of the pressed and depressed events.

static void click_config_provider(void *context) {
  ButtonId id = BUTTON_ID_SELECT;  // The select button

  window_raw_click_subscribe(id, raw_down_click_handler, raw_up_click_handler,
                                                                        NULL);
}

The last parameter is an optional pointer to a context object to be passed to the callback, and is set to NULL if not used.

Overview

  • Listening for Button Clicks
  • Types of Click Events
  • Single Clicks
  • Single Repeating Clicks
  • Multiple Clicks
  • Long Clicks
  • Raw Clicks

Related SDK Docs

  • Clicks
  • ClickHandler

Examples

  • App Font Browser