For Pebble SDK 3.0 tutorials and documentation, I wrote some for Pebble! Official Developer Documentation

 

Introduction

This is the contents page for my Pebble SDK Tutorial. The first two parts are aimed at beginners to the C language, but all parts have that perspective built in, with the prior knowledge gained from previous parts assumed for later parts, letting the reader mature.

Please feel free to add a comment for questions, suggestions and extra parts, and I’ll do my best to respond.

SDK 2.0 Tutorial

This version of the tutorial is obsolete now 3.0 is released, but still serves as an example of how a more modern SDK is operated.

The source code for these tutorials is now available in the pebble-archive repository!

  1. Your First Watchapp

  2. Telling the Time

  3. Images and Fonts

  4. Animations and Timers

  5. Buttons and Vibrations

  6. AppMessage for PebbleKit JS

  7. MenuLayers

  8. Android App Integration

  9. App Configuration

  10. Event Services

SDK 1.X Tutorial

This version of the tutorial is obsolete now 2.0 is released, but still serves as an example of how the Pebble SDK operates and is put together.

  1. Beginner’s Primer to the C Language

  2. Applying the Primer to the Pebble SDK

  3. Setting up a Ubuntu Virtual Machine for Development

  4. Anatomy of Your First Watch Face

  5. Animations, Images and Fonts

  6. 2 Way Communication with Android

  7. ScrollLayers

13 comments
  1. Kheng Cheng Wai said:

    Can the two way communication work on SDK 2.0?

    • bonsitm said:

      Yes indeed, see section 7! Android specific code stays largely the same and may be revisited soon.

    • bonsitm said:

      Hi Kheng, the two way communication section is now done for 2.0!

  2. Carl said:

    Hello Chris!

    First of all, thank you for a great tutorial, I am just getting into development for the Pebble and have been learning a great deal of new stuff from your blog. Now to my question: Would it be possible for you to show a short tutorial regarding how to link all together? I mean, I have managed to build a watchapp, have it display time and date, make it do stuff when I push the buttons, but then what? 🙂 I would just need a nod in the right direction with setting up a watchapp with a default “on load” window, pushing a button to create (what I am guessing would be) a new window with new information, pushing back button to come back to the default window, etc. I have been browsing both Github and SO as well as the forums without being able to find a suitable example to play (and learn) with.

    • bonsitm said:

      Hi Carl, thanks for the kind words. The Pebble SDK works nicely in that each Window has its load and unload handlers. This means that when you call window_stack_push(), the load is called for you, and when the user presses BACK unload is also called for you.

      As long as you do all the correct creating in each window’s assigned load handler and destroying in the corresponding unload handler, all you have to do it call window_stack_push()! The rest is done for you.

      If this isn’t clear still, I can make a simple two-window demo if you like.

      • Carl said:

        Hello again, thank you for your fast reply 🙂
        Currently, I am struggling with two things that I can’t seem to get my head around:
        1. This whole window business discussed earlier,
        2. How to create text layers in windows using different time units (IE: Top screen layer updates each minute, bottom screen layer updates every fifteen minutes).

        Beggars can’t be choosers, so if you could make a small demo of the windows I would be a happy man (and have something to do for the weekend 😉

      • bonsitm said:

        That is fine, I will create a small demo when I am able. Stay tuned!

      • bonsitm said:

        Here’s your demo. Remember each Window takes care of itself with the .load and .unload handlers, but can be pushed from each other!


        #include <pebble.h>
        static Window *window_1, *window_2;
        static TextLayer *text_layer_1, *text_layer_2;
        /********************************* Window 2 stuff ***********************************/
        static void window_2_load(Window *window) {
        text_layer_2 = text_layer_create(GRect(0, 0, 144, 168));
        text_layer_set_text(text_layer_2, "Window 2. \nBACK for Window 1.");
        text_layer_set_text_alignment(text_layer_2, GTextAlignmentLeft);
        text_layer_set_font(text_layer_2, fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD));
        layer_add_child(window_get_root_layer(window), text_layer_get_layer(text_layer_2));
        }
        static void window_2_unload(Window *window) {
        text_layer_destroy(text_layer_2);
        //Careful with this
        window_destroy(window_2);
        }
        /********************************* Window 1 stuff ***********************************/
        static void select_click_handler(ClickRecognizerRef recognizer, void *context) {
        //Load window 2
        window_2 = window_create();
        window_set_window_handlers(window_2, (WindowHandlers) {
        .load = window_2_load,
        .unload = window_2_unload,
        });
        window_stack_push(window_2, true); //That's all there is too it!
        }
        static void click_config_provider(void *context) {
        window_single_click_subscribe(BUTTON_ID_SELECT, select_click_handler);
        }
        static void window_1_load(Window *window) {
        text_layer_1 = text_layer_create(GRect(0, 0, 144, 168));
        text_layer_set_text(text_layer_1, "Window 1. \nSELECT for Window 2.");
        text_layer_set_text_alignment(text_layer_1, GTextAlignmentLeft);
        text_layer_set_font(text_layer_1, fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD));
        layer_add_child(window_get_root_layer(window), text_layer_get_layer(text_layer_1));
        }
        static void window_1_unload(Window *window) {
        text_layer_destroy(text_layer_1);
        window_destroy(window_1);
        }
        /******************************** Main app stuff ************************************/
        static void init(void) {
        //Start with window 1
        window_1 = window_create();
        window_set_click_config_provider(window_1, click_config_provider);
        window_set_window_handlers(window_1, (WindowHandlers) {
        .load = window_1_load,
        .unload = window_1_unload,
        });
        window_stack_push(window_1, true);
        }
        static void deinit(void) {
        }
        int main(void) {
        init();
        app_event_loop();
        deinit();
        }

        view raw

        twowindows.c

        hosted with ❤ by GitHub

  3. Carl said:

    Wow, this is just… Wow. Thank you, I can now make sense of this whole thing. Made my weekend!

  4. Hi Chris,

    This tutorial series is fantastic. Really appreciate you taking the time to put all this together to help other people. Really helped me in the development of my first watchface – would likely have given up long ago in frustration without your work as a reference.

    Thank You!
    Conor.

    • bonsitm said:

      Thanks Conor! Best of luck with your apps!

Leave a comment